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