16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   Copyright (C) 1996-2012, International Business Machines                 *
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   Corporation and others.  All Rights Reserved.                            *
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_COLLATION
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/unistr.h"
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/usearch.h"
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/coll.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/tblcoll.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/coleitr.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucoleitr.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/regex.h"        // TODO: make conditional on regexp being built.
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uniset.h"
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uset.h"
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h"
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "hash.h"
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uhash.h"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucol_imp.h"
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h"
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "colldata.h"
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define NEW_ARRAY(type, count) (type *) uprv_malloc((count) * sizeof(type))
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DELETE_ARRAY(array) uprv_free((void *) (array))
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ARRAY_COPY(dst, src, count) uprv_memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0])
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCEList::CEList(UCollator *coll, const UnicodeString &string, UErrorCode &status)
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    : ces(NULL), listMax(CELIST_BUFFER_SIZE), listSize(0)
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCollationElements *elems = ucol_openElements(coll, string.getBuffer(), string.length(), &status);
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCollationStrength strength = ucol_getStrength(coll);
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool toShift = ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, &status) ==  UCOL_SHIFTED;
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t variableTop = ucol_getVariableTop(coll, &status);
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t strengthMask = 0;
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t order;
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // **** only set flag if string has Han(gul) ****
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucol_forceHanImplicit(elems, &status);
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (strength)
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strengthMask |= UCOL_TERTIARYORDERMASK;
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* fall through */
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UCOL_SECONDARY:
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strengthMask |= UCOL_SECONDARYORDERMASK;
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* fall through */
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UCOL_PRIMARY:
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strengthMask |= UCOL_PRIMARYORDERMASK;
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ces = ceBuffer;
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while ((order = ucol_next(elems, &status)) != UCOL_NULLORDER) {
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UBool cont = isContinuation(order);
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        order &= strengthMask;
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (toShift && variableTop > (uint32_t)order && (order & UCOL_PRIMARYORDERMASK) != 0) {
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (strength >= UCOL_QUATERNARY) {
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                order &= UCOL_PRIMARYORDERMASK;
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                order = UCOL_IGNORABLE;
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (order == UCOL_IGNORABLE) {
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            continue;
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (cont) {
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            order |= UCOL_CONTINUATION_MARKER;
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        add(order, status);
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucol_closeElements(elems);
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCEList::~CEList()
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (ces != ceBuffer) {
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        DELETE_ARRAY(ces);
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CEList::add(uint32_t ce, UErrorCode &status)
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (listSize >= listMax) {
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t newMax = listMax + CELIST_BUFFER_SIZE;
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uint32_t *newCEs = NEW_ARRAY(uint32_t, newMax);
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (newCEs == NULL) {
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return;
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_memcpy(newCEs, ces, listSize * sizeof(uint32_t));
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ces != ceBuffer) {
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            DELETE_ARRAY(ces);
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ces = newCEs;
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        listMax = newMax;
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ces[listSize++] = ce;
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguint32_t CEList::get(int32_t index) const
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (index >= 0 && index < listSize) {
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ces[index];
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (uint32_t)UCOL_NULLORDER;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguint32_t &CEList::operator[](int32_t index) const
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ces[index];
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool CEList::matchesAt(int32_t offset, const CEList *other) const
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (other == NULL || listSize - offset < other->size()) {
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i = offset, j = 0; j < other->size(); i += 1, j += 1) {
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ces[i] != (*other)[j]) {
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return FALSE;
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t CEList::size() const
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return listSize;
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringList::StringList(UErrorCode &status)
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    : strings(NULL), listMax(STRING_LIST_BUFFER_SIZE), listSize(0)
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    strings = new UnicodeString [listMax];
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (strings == NULL) {
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_MEMORY_ALLOCATION_ERROR;
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringList::~StringList()
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete[] strings;
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid StringList::add(const UnicodeString *string, UErrorCode &status)
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (listSize >= listMax) {
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t newMax = listMax + STRING_LIST_BUFFER_SIZE;
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString *newStrings = new UnicodeString[newMax];
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (newStrings == NULL) {
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return;
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (int32_t i=0; i<listSize; ++i) {
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            newStrings[i] = strings[i];
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete[] strings;
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strings = newStrings;
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        listMax = newMax;
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // The ctor initialized all the strings in
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // the array to empty strings, so this
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // is the same as copying the source string.
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    strings[listSize++].append(*string);
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid StringList::add(const UChar *chars, int32_t count, UErrorCode &status)
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UnicodeString string(chars, count);
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    add(&string, status);
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString *StringList::get(int32_t index) const
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (index >= 0 && index < listSize) {
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return &strings[index];
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t StringList::size() const
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return listSize;
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteStringList(void *obj)
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    StringList *strings = (StringList *) obj;
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete strings;
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass CEToStringsMap
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    CEToStringsMap(UErrorCode &status);
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ~CEToStringsMap();
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    void put(uint32_t ce, UnicodeString *string, UErrorCode &status);
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    StringList *getStringList(uint32_t ce) const;
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate:
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    void putStringList(uint32_t ce, StringList *stringList, UErrorCode &status);
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UHashtable *map;
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCEToStringsMap::CEToStringsMap(UErrorCode &status)
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    : map(NULL)
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    map = uhash_open(uhash_hashLong, uhash_compareLong,
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     uhash_compareCaselessUnicodeString,
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     &status);
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uhash_setValueDeleter(map, deleteStringList);
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCEToStringsMap::~CEToStringsMap()
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uhash_close(map);
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CEToStringsMap::put(uint32_t ce, UnicodeString *string, UErrorCode &status)
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    StringList *strings = getStringList(ce);
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (strings == NULL) {
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        strings = new StringList(status);
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (strings == NULL || U_FAILURE(status)) {
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return;
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        putStringList(ce, strings, status);
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    strings->add(string, status);
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringList *CEToStringsMap::getStringList(uint32_t ce) const
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (StringList *) uhash_iget(map, ce);
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CEToStringsMap::putStringList(uint32_t ce, StringList *stringList, UErrorCode &status)
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uhash_iput(map, ce, (void *) stringList, &status);
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define CLONE_COLLATOR
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCollData::CollData(UCollator *collator, UErrorCode &status)
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    : coll(NULL), ceToCharsStartingWith(NULL)
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // [:c:] == [[:cn:][:cc:][:co:][:cf:][:cs:]]
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // i.e. other, control, private use, format, surrogate
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_STRING_DECL(test_pattern, "[[:assigned:]-[:c:]]", 20);
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_STRING_INIT(test_pattern, "[[:assigned:]-[:c:]]", 20);
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    USet *charsToTest = uset_openPattern(test_pattern, 20, &status);
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Han ext. A, Han, Jamo, Hangul, Han Ext. B
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // i.e. all the characers we handle implicitly
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_STRING_DECL(remove_pattern, "[[\\u3400-\\u9FFF][\\u1100-\\u11F9][\\uAC00-\\uD7AF][\\U00020000-\\U0002A6DF]]", 70);
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_STRING_INIT(remove_pattern, "[[\\u3400-\\u9FFF][\\u1100-\\u11F9][\\uAC00-\\uD7AF][\\U00020000-\\U0002A6DF]]", 70);
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    USet *charsToRemove = uset_openPattern(remove_pattern, 70, &status);
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    USet *expansions   = uset_openEmpty();
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    USet *contractions = uset_openEmpty();
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t itemCount;
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ceToCharsStartingWith = new CEToStringsMap(status);
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto bail;
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef CLONE_COLLATOR
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    coll = ucol_safeClone(collator, NULL, NULL, &status);
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto bail;
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    coll = collator;
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucol_getContractionsAndExpansions(coll, contractions, expansions, FALSE, &status);
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_addAll(charsToTest, contractions);
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_addAll(charsToTest, expansions);
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_removeAll(charsToTest, charsToRemove);
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    itemCount = uset_getItemCount(charsToTest);
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(int32_t item = 0; item < itemCount; item += 1) {
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar32 start = 0, end = 0;
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar buffer[16];
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t len = uset_getItem(charsToTest, item, &start, &end,
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   buffer, 16, &status);
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (len == 0) {
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for (UChar32 ch = start; ch <= end; ch += 1) {
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UnicodeString *st = new UnicodeString(ch);
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (st == NULL) {
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    status = U_MEMORY_ALLOCATION_ERROR;
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                CEList *ceList = new CEList(coll, *st, status);
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ceToCharsStartingWith->put(ceList->get(0), st, status);
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete ceList;
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete st;
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (len > 0) {
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UnicodeString *st = new UnicodeString(buffer, len);
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (st == NULL) {
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                status = U_MEMORY_ALLOCATION_ERROR;
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            CEList *ceList = new CEList(coll, *st, status);
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ceToCharsStartingWith->put(ceList->get(0), st, status);
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete ceList;
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete st;
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // shouldn't happen...
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_FAILURE(status)) {
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             break;
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbail:
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_close(contractions);
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_close(expansions);
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_close(charsToRemove);
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uset_close(charsToTest);
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     UChar32 hanRanges[] = {UCOL_FIRST_HAN, UCOL_LAST_HAN, UCOL_FIRST_HAN_COMPAT, UCOL_LAST_HAN_COMPAT, UCOL_FIRST_HAN_A, UCOL_LAST_HAN_A,
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            UCOL_FIRST_HAN_B, UCOL_LAST_HAN_B};
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     UChar  jamoRanges[] = {UCOL_FIRST_L_JAMO, UCOL_FIRST_V_JAMO, UCOL_FIRST_T_JAMO, UCOL_LAST_T_JAMO};
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     UnicodeString hanString = UnicodeString::fromUTF32(hanRanges, ARRAY_SIZE(hanRanges));
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     UnicodeString jamoString(FALSE, jamoRanges, ARRAY_SIZE(jamoRanges));
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     CEList hanList(coll, hanString, status);
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     CEList jamoList(coll, jamoString, status);
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     int32_t j = 0;
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     if (U_FAILURE(status)) {
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         return;
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     }
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     for (int32_t c = 0; c < jamoList.size(); c += 1) {
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         uint32_t jce = jamoList[c];
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if (! isContinuation(jce)) {
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             jamoLimits[j++] = jce;
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     }
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     jamoLimits[3] += (1 << UCOL_PRIMARYORDERSHIFT);
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     minHan = 0xFFFFFFFF;
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     maxHan = 0;
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     for(int32_t h = 0; h < hanList.size(); h += 2) {
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         uint32_t han = (uint32_t) hanList[h];
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if (han < minHan) {
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             minHan = han;
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if (han > maxHan) {
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             maxHan = han;
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     }
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     maxHan += (1 << UCOL_PRIMARYORDERSHIFT);
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCollData::~CollData()
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef CLONE_COLLATOR
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org   ucol_close(coll);
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org   delete ceToCharsStartingWith;
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUCollator *CollData::getCollator() const
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return coll;
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst StringList *CollData::getStringList(int32_t ce) const
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ceToCharsStartingWith->getStringList(ce);
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst CEList *CollData::getCEList(const UnicodeString *string) const
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode status = U_ZERO_ERROR;
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const CEList *list = new CEList(coll, *string, status);
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete list;
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        list = NULL;
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return list;
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CollData::freeCEList(const CEList *list)
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete list;
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t CollData::minLengthInChars(const CEList *ceList, int32_t offset, int32_t *history) const
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // find out shortest string for the longest sequence of ces.
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // this can probably be folded with the minLengthCache...
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (history[offset] >= 0) {
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return history[offset];
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t ce = ceList->get(offset);
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t maxOffset = ceList->size();
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t shortestLength = INT32_MAX;
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const StringList *strings = ceToCharsStartingWith->getStringList(ce);
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (strings != NULL) {
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t stringCount = strings->size();
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (int32_t s = 0; s < stringCount; s += 1) {
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const UnicodeString *string = strings->get(s);
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UErrorCode status = U_ZERO_ERROR;
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const CEList *ceList2 = new CEList(coll, *string, status);
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete ceList2;
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ceList2 = NULL;
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (ceList->matchesAt(offset, ceList2)) {
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                U_ASSERT(ceList2 != NULL);
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int32_t clength = ceList2->size();
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int32_t slength = string->length();
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int32_t roffset = offset + clength;
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int32_t rlength = 0;
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (roffset < maxOffset) {
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    rlength = minLengthInChars(ceList, roffset, history);
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (rlength <= 0) {
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    // delete before continue to avoid memory leak.
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        delete ceList2;
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        // ignore any dead ends
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        continue;
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (shortestLength > slength + rlength) {
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    shortestLength = slength + rlength;
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete ceList2;
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (shortestLength == INT32_MAX) {
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // No matching strings at this offset. See if
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // the CE is in a range we can handle manually.
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ce >= minHan && ce < maxHan) {
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // all han have implicit orders which
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // generate two CEs.
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t roffset = offset + 2;
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t rlength = 0;
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          //history[roffset++] = -1;
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          //history[roffset++] = 1;
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (roffset < maxOffset) {
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                rlength = minLengthInChars(ceList, roffset, history);
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (rlength < 0) {
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return -1;
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            shortestLength = 1 + rlength;
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            goto have_shortest;
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (ce >= jamoLimits[0] && ce < jamoLimits[3]) {
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t roffset = offset;
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t rlength = 0;
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // **** this loop may not handle archaic Hangul correctly ****
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for (int32_t j = 0; roffset < maxOffset && j < 4; j += 1, roffset += 1) {
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                uint32_t jce = ceList->get(roffset);
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // Some Jamo have 24-bit primary order; skip the
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // 2nd CE. This should always be OK because if
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // we're still in the loop all we've seen are
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // a series of Jamo in LVT order.
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (isContinuation(jce)) {
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    continue;
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (j >= 3 || jce < jamoLimits[j] || jce >= jamoLimits[j + 1]) {
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (roffset == offset) {
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // we started with a non-L Jamo...
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // just say it comes from a single character
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                roffset += 1;
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // See if the single Jamo has a 24-bit order.
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (roffset < maxOffset && isContinuation(ceList->get(roffset))) {
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    roffset += 1;
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (roffset < maxOffset) {
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                rlength = minLengthInChars(ceList, roffset, history);
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (rlength < 0) {
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return -1;
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            shortestLength = 1 + rlength;
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            goto have_shortest;
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Can't handle it manually either. Just move on.
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orghave_shortest:
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    history[offset] = shortestLength;
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return shortestLength;
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t CollData::minLengthInChars(const CEList *ceList, int32_t offset) const
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t clength = ceList->size();
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t *history = NEW_ARRAY(int32_t, clength);
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i = 0; i < clength; i += 1) {
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        history[i] = -1;
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t minLength = minLengthInChars(ceList, offset, history);
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    DELETE_ARRAY(history);
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return minLength;
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif // #if !UCONFIG_NO_COLLATION
639