15870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov/* 25870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project 35870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * 45870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 55870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * you may not use this file except in compliance with the License. 65870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * You may obtain a copy of the License at 75870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * 85870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 95870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * 105870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 115870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 125870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * See the License for the specific language governing permissions and 145870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * limitations under the License 155870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov */ 165870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 175870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovpackage com.android.providers.contacts; 185870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 195870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovimport java.util.ArrayList; 205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov/** 225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Contacts lookup key. Used for generation and parsing of contact lookup keys as well 235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * as doing the actual lookup. 245870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov */ 255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovpublic class ContactLookupKey { 265870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2792fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public static final int LOOKUP_TYPE_SOURCE_ID = 0; 2892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public static final int LOOKUP_TYPE_DISPLAY_NAME = 1; 2992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public static final int LOOKUP_TYPE_RAW_CONTACT_ID = 2; 305d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro public static final int LOOKUP_TYPE_PROFILE = 3; 315d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro 325d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // The Profile contact will always have a lookup key of "profile". 335d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro public static final String PROFILE_LOOKUP_KEY = "profile"; 3492fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov 355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public static class LookupKeySegment implements Comparable<LookupKeySegment> { 365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public int accountHashCode; 3792fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public int lookupType; 3892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public String rawContactId; 395870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public String key; 405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public long contactId; 415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public int compareTo(LookupKeySegment another) { 435870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (contactId > another.contactId) { 445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return -1; 455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (contactId < another.contactId) { 475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return 1; 485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 495870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return 0; 505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov /** 545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Returns a short hash code that functions as an additional precaution against the exceedingly 555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * improbable collision between sync IDs in different accounts. 565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov */ 5743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro public static int getAccountHashCode(String accountTypeWithDataSet, String accountName) { 5843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro if (accountTypeWithDataSet == null || accountName == null) { 595870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return 0; 605870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 615870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 6243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro return (accountTypeWithDataSet.hashCode() ^ accountName.hashCode()) & 0xFFF; 635870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 645870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 65c5fdfb79564e8b46d6aae213a312d4e1560f3a3cDave Santoro public static void appendToLookupKey(StringBuilder lookupKey, String accountTypeWithDataSet, 6643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro String accountName, long rawContactId, String sourceId, 6743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro String displayName) { 68e2a3fb8c60d68aaef5f20587e5c9cb3f6f3ffa22Megha Joshi if (displayName == null) { 69e2a3fb8c60d68aaef5f20587e5c9cb3f6f3ffa22Megha Joshi displayName = ""; 70cf80ca3101d80a431809c3bec834bc329416ae99Dmitri Plotnikov } 71cf80ca3101d80a431809c3bec834bc329416ae99Dmitri Plotnikov 725870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (lookupKey.length() != 0) { 735870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupKey.append("."); 745870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 755870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 76c5fdfb79564e8b46d6aae213a312d4e1560f3a3cDave Santoro lookupKey.append(getAccountHashCode(accountTypeWithDataSet, accountName)); 775870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (sourceId == null) { 7892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupKey.append('r').append(rawContactId).append('-').append( 7992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov NameNormalizer.normalize(displayName)); 805870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 815870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int pos = lookupKey.length(); 825870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupKey.append('i'); 835870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (appendEscapedSourceId(lookupKey, sourceId)) { 845870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupKey.setCharAt(pos, 'e'); 855870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 865870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 875870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 885870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 89285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov private static boolean appendEscapedSourceId(StringBuilder sb, String sourceId) { 905870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov boolean escaped = false; 915870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int start = 0; 925870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (true) { 935870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int index = sourceId.indexOf('.', start); 945870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (index == -1) { 955870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(sourceId, start, sourceId.length()); 965870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 975870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 985870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 995870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov escaped = true; 1005870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(sourceId, start, index); 1015870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(".."); 1025870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov start = index + 1; 1035870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1045870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return escaped; 1055870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1075870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public ArrayList<LookupKeySegment> parse(String lookupKey) { 1085870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ArrayList<LookupKeySegment> list = new ArrayList<LookupKeySegment>(); 1095870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1105d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // If the lookup key is for the profile, just return a segment list indicating that. The 1115d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // caller should already be in a context in which the only contact in the database is the 1125d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // user's profile. 1135d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro if (PROFILE_LOOKUP_KEY.equals(lookupKey)) { 1145d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro LookupKeySegment profileSegment = new LookupKeySegment(); 1155d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro profileSegment.lookupType = LOOKUP_TYPE_PROFILE; 1165d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro list.add(profileSegment); 1175d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro return list; 1185d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro } 1195d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro 1206d6b2a5cd3d639bb0f878334b46720845ef92aa6Jay Shrauner String string = lookupKey; 1215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int offset = 0; 1225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int length = string.length(); 1235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int hashCode = 0; 12492fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov int lookupType = -1; 125e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov boolean escaped = false; 12692fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov String rawContactId = null; 1275870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String key; 1285870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1295870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (offset < length) { 1305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov char c = 0; 1315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // Parse account hash code 1335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov hashCode = 0; 1345870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (offset < length) { 1355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov c = string.charAt(offset++); 1365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (c < '0' || c > '9') { 1375870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 1385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1395870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov hashCode = hashCode * 10 + (c - '0'); 1405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // Parse segment type 14392fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov if (c == 'i') { 14492fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_SOURCE_ID; 1455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov escaped = false; 1465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else if (c == 'e') { 14792fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_SOURCE_ID; 1485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov escaped = true; 14992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov } else if (c == 'n') { 15092fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_DISPLAY_NAME; 15192fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov } else if (c == 'r') { 15292fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_RAW_CONTACT_ID; 1535e854ef150a090cd0e77f2b9ebf4ef8609ac6135Tony Mak } else if (c == 'c') { 1545e854ef150a090cd0e77f2b9ebf4ef8609ac6135Tony Mak throw new IllegalArgumentException( 1555e854ef150a090cd0e77f2b9ebf4ef8609ac6135Tony Mak "Work contact lookup key is not accepted here: " + lookupKey); 1565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 1575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov throw new IllegalArgumentException("Invalid lookup id: " + lookupKey); 1585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1595870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1605870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // Parse the source ID or normalized display name 161e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov switch (lookupType) { 162e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov case LOOKUP_TYPE_SOURCE_ID: { 163e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (escaped) { 164e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov StringBuffer sb = new StringBuffer(); 165e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 166e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset++); 167e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov 16851698db0c97b20e95421bc42b243e4ea315137beDmitri Plotnikov if (c == '.') { 169e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (offset == length) { 170e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov throw new IllegalArgumentException("Invalid lookup id: " + 171e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov lookupKey); 172e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 173e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset); 174e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov 175e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '.') { 176e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov sb.append('.'); 177e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov offset++; 178e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 179e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 180e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 181e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 182e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov sb.append(c); 183e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 184e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 185e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = sb.toString(); 186e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 187e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int start = offset; 188e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 189e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset++); 190e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '.') { 191e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 192e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 193e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 1945870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (offset == length) { 195e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start); 196e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 197e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start, offset - 1); 1985870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 199e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 200e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 201e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 202e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov case LOOKUP_TYPE_DISPLAY_NAME: { 203e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int start = offset; 204e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 205e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset++); 2065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (c == '.') { 2075870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 2085870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 209e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 210e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (offset == length) { 211e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start); 2125870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 213e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start, offset - 1); 2145870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 215e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 2165870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 217e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov case LOOKUP_TYPE_RAW_CONTACT_ID: { 218e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int dash = -1; 219e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int start = offset; 220e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 221e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset); 222e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '-' && dash == -1) { 223e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov dash = offset; 224e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 225e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov offset++; 226e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '.') { 227e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 228e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 22992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov } 230e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (dash != -1) { 231e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov rawContactId = string.substring(start, dash); 232e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov start = dash + 1; 2335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 234e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (offset == length) { 235e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start); 236e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 237e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start, offset - 1); 238e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 239e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 2405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 241e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov default: 242e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov // Will never happen 243e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov throw new IllegalStateException(); 2445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = new LookupKeySegment(); 2475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.accountHashCode = hashCode; 24892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov segment.lookupType = lookupType; 24992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov segment.rawContactId = rawContactId; 2505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.key = key; 2515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.contactId = -1; 2525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov list.add(segment); 2535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return list; 2565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov} 258