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 android.net.Uri; 205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovimport java.util.ArrayList; 225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov/** 245870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Contacts lookup key. Used for generation and parsing of contact lookup keys as well 255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * as doing the actual lookup. 265870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov */ 275870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovpublic class ContactLookupKey { 285870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public static final int LOOKUP_TYPE_SOURCE_ID = 0; 3092fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public static final int LOOKUP_TYPE_DISPLAY_NAME = 1; 3192fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public static final int LOOKUP_TYPE_RAW_CONTACT_ID = 2; 325d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro public static final int LOOKUP_TYPE_PROFILE = 3; 335d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro 345d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // The Profile contact will always have a lookup key of "profile". 355d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro public static final String PROFILE_LOOKUP_KEY = "profile"; 3692fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov 375870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public static class LookupKeySegment implements Comparable<LookupKeySegment> { 385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public int accountHashCode; 3992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public int lookupType; 4092fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov public String rawContactId; 415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public String key; 425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public long contactId; 435870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public int compareTo(LookupKeySegment another) { 455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (contactId > another.contactId) { 465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return -1; 475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (contactId < another.contactId) { 495870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return 1; 505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return 0; 525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov /** 565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Returns a short hash code that functions as an additional precaution against the exceedingly 575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * improbable collision between sync IDs in different accounts. 585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov */ 5943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro public static int getAccountHashCode(String accountTypeWithDataSet, String accountName) { 6043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro if (accountTypeWithDataSet == null || accountName == null) { 615870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return 0; 625870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 635870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 6443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro return (accountTypeWithDataSet.hashCode() ^ accountName.hashCode()) & 0xFFF; 655870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 665870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 67c5fdfb79564e8b46d6aae213a312d4e1560f3a3cDave Santoro public static void appendToLookupKey(StringBuilder lookupKey, String accountTypeWithDataSet, 6843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro String accountName, long rawContactId, String sourceId, 6943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro String displayName) { 70e2a3fb8c60d68aaef5f20587e5c9cb3f6f3ffa22Megha Joshi if (displayName == null) { 71e2a3fb8c60d68aaef5f20587e5c9cb3f6f3ffa22Megha Joshi displayName = ""; 72cf80ca3101d80a431809c3bec834bc329416ae99Dmitri Plotnikov } 73cf80ca3101d80a431809c3bec834bc329416ae99Dmitri Plotnikov 745870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (lookupKey.length() != 0) { 755870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupKey.append("."); 765870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 775870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 78c5fdfb79564e8b46d6aae213a312d4e1560f3a3cDave Santoro lookupKey.append(getAccountHashCode(accountTypeWithDataSet, accountName)); 795870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (sourceId == null) { 8092fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupKey.append('r').append(rawContactId).append('-').append( 8192fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov NameNormalizer.normalize(displayName)); 825870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 835870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int pos = lookupKey.length(); 845870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupKey.append('i'); 855870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (appendEscapedSourceId(lookupKey, sourceId)) { 865870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupKey.setCharAt(pos, 'e'); 875870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 885870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 895870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 905870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 91285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov private static boolean appendEscapedSourceId(StringBuilder sb, String sourceId) { 925870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov boolean escaped = false; 935870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int start = 0; 945870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (true) { 955870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int index = sourceId.indexOf('.', start); 965870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (index == -1) { 975870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(sourceId, start, sourceId.length()); 985870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 995870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1005870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1015870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov escaped = true; 1025870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(sourceId, start, index); 1035870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(".."); 1045870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov start = index + 1; 1055870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return escaped; 1075870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1085870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1095870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov public ArrayList<LookupKeySegment> parse(String lookupKey) { 1105870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ArrayList<LookupKeySegment> list = new ArrayList<LookupKeySegment>(); 1115870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1125d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // If the lookup key is for the profile, just return a segment list indicating that. The 1135d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // caller should already be in a context in which the only contact in the database is the 1145d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro // user's profile. 1155d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro if (PROFILE_LOOKUP_KEY.equals(lookupKey)) { 1165d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro LookupKeySegment profileSegment = new LookupKeySegment(); 1175d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro profileSegment.lookupType = LOOKUP_TYPE_PROFILE; 1185d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro list.add(profileSegment); 1195d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro return list; 1205d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro } 1215d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro 1225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String string = Uri.decode(lookupKey); 1235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int offset = 0; 1245870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int length = string.length(); 1255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int hashCode = 0; 12692fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov int lookupType = -1; 127e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov boolean escaped = false; 12892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov String rawContactId = null; 1295870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String key; 1305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (offset < length) { 1325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov char c = 0; 1335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1345870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // Parse account hash code 1355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov hashCode = 0; 1365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (offset < length) { 1375870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov c = string.charAt(offset++); 1385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (c < '0' || c > '9') { 1395870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 1405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov hashCode = hashCode * 10 + (c - '0'); 1425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1435870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // Parse segment type 14592fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov if (c == 'i') { 14692fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_SOURCE_ID; 1475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov escaped = false; 1485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else if (c == 'e') { 14992fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_SOURCE_ID; 1505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov escaped = true; 15192fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov } else if (c == 'n') { 15292fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_DISPLAY_NAME; 15392fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov } else if (c == 'r') { 15492fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov lookupType = LOOKUP_TYPE_RAW_CONTACT_ID; 1555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 1565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov throw new IllegalArgumentException("Invalid lookup id: " + lookupKey); 1575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 1585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 1595870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // Parse the source ID or normalized display name 160e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov switch (lookupType) { 161e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov case LOOKUP_TYPE_SOURCE_ID: { 162e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (escaped) { 163e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov StringBuffer sb = new StringBuffer(); 164e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 165e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset++); 166e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov 16751698db0c97b20e95421bc42b243e4ea315137beDmitri Plotnikov if (c == '.') { 168e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (offset == length) { 169e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov throw new IllegalArgumentException("Invalid lookup id: " + 170e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov lookupKey); 171e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 172e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset); 173e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov 174e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '.') { 175e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov sb.append('.'); 176e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov offset++; 177e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 178e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 179e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 180e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 181e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov sb.append(c); 182e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 183e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 184e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = sb.toString(); 185e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 186e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int start = offset; 187e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 188e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset++); 189e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '.') { 190e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 191e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 192e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 1935870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (offset == length) { 194e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start); 195e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 196e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start, offset - 1); 1975870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 198e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 199e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 200e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 201e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov case LOOKUP_TYPE_DISPLAY_NAME: { 202e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int start = offset; 203e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 204e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset++); 2055870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (c == '.') { 2065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 2075870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 208e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 209e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (offset == length) { 210e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start); 2115870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 212e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start, offset - 1); 2135870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 214e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 2155870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 216e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov case LOOKUP_TYPE_RAW_CONTACT_ID: { 217e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int dash = -1; 218e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov int start = offset; 219e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov while (offset < length) { 220e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov c = string.charAt(offset); 221e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '-' && dash == -1) { 222e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov dash = offset; 223e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 224e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov offset++; 225e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (c == '.') { 226e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 227e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 22892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov } 229e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (dash != -1) { 230e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov rawContactId = string.substring(start, dash); 231e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov start = dash + 1; 2325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 233e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov if (offset == length) { 234e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start); 235e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } else { 236e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov key = string.substring(start, offset - 1); 237e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov } 238e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov break; 2395870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 240e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov default: 241e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov // Will never happen 242e0bbba6a6026b2577e62097ea8f8f7ebe48da8f5Dmitri Plotnikov throw new IllegalStateException(); 2435870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = new LookupKeySegment(); 2465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.accountHashCode = hashCode; 24792fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov segment.lookupType = lookupType; 24892fcdfb24194e8527ef59c0af0731825ee46fa45Dmitri Plotnikov segment.rawContactId = rawContactId; 2495870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.key = key; 2505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.contactId = -1; 2515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov list.add(segment); 2525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return list; 2555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov} 257