16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2013, International Business Machines
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others.  All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* dictionarydata.h
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 2012may31
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer & Maxime Serrano
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "dictionarydata.h"
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucharstrie.h"
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/bytestrie.h"
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/udata.h"
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_BREAK_ITERATION
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRIE_TYPE_BYTES = 0;
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRIE_TYPE_UCHARS = 1;
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRIE_TYPE_MASK = 7;
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRIE_HAS_VALUES = 8;
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRANSFORM_NONE = 0;
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRANSFORM_TYPE_OFFSET = 0x1000000;
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRANSFORM_TYPE_MASK = 0x7f000000;
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t  DictionaryData::TRANSFORM_OFFSET_MASK = 0x1fffff;
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgDictionaryMatcher::~DictionaryMatcher() {
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUCharsDictionaryMatcher::~UCharsDictionaryMatcher() {
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udata_close(file);
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t UCharsDictionaryMatcher::getType() const {
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return DictionaryData::TRIE_TYPE_UCHARS;
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t UCharsDictionaryMatcher::matches(UText *text, int32_t maxLength, int32_t *lengths, int32_t &count, int32_t limit, int32_t *values) const {
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCharsTrie uct(characters);
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c = utext_next32(text);
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (c < 0) {
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UStringTrieResult result = uct.first(c);
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t numChars = 1;
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = 0;
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (;;) {
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (USTRINGTRIE_HAS_VALUE(result)) {
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (count < limit) {
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (values != NULL) {
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    values[count] = uct.getValue();
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                lengths[count++] = numChars;
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (result == USTRINGTRIE_FINAL_VALUE) {
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else if (result == USTRINGTRIE_NO_MATCH) {
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // TODO: why do we have a text limit if the UText knows its length?
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (numChars >= maxLength) {
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        c = utext_next32(text);
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (c < 0) {
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ++numChars;
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = uct.next(c);
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return numChars;
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBytesDictionaryMatcher::~BytesDictionaryMatcher() {
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udata_close(file);
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUChar32 BytesDictionaryMatcher::transform(UChar32 c) const {
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if ((transformConstant & DictionaryData::TRANSFORM_TYPE_MASK) == DictionaryData::TRANSFORM_TYPE_OFFSET) {
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (c == 0x200D) {
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0xFF;
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (c == 0x200C) {
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0xFE;
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t delta = c - (transformConstant & DictionaryData::TRANSFORM_OFFSET_MASK);
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (delta < 0 || 0xFD < delta) {
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return U_SENTINEL;
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return (UChar32)delta;
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return c;
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t BytesDictionaryMatcher::getType() const {
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return DictionaryData::TRIE_TYPE_BYTES;
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t BytesDictionaryMatcher::matches(UText *text, int32_t maxLength, int32_t *lengths, int32_t &count, int32_t limit, int32_t *values) const {
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    BytesTrie bt(characters);
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c = utext_next32(text);
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (c < 0) {
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UStringTrieResult result = bt.first(transform(c));
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t numChars = 1;
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = 0;
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (;;) {
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (USTRINGTRIE_HAS_VALUE(result)) {
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (count < limit) {
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (values != NULL) {
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    values[count] = bt.getValue();
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                lengths[count++] = numChars;
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (result == USTRINGTRIE_FINAL_VALUE) {
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else if (result == USTRINGTRIE_NO_MATCH) {
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // TODO: why do we have a text limit if the UText knows its length?
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (numChars >= maxLength) {
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        c = utext_next32(text);
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (c < 0) {
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ++numChars;
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = bt.next(transform(c));
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return numChars;
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_USE
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgudict_swap(const UDataSwapper *ds, const void *inData, int32_t length,
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           void *outData, UErrorCode *pErrorCode) {
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize;
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *inBytes;
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t *outBytes;
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const int32_t *inIndexes;
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t indexes[DictionaryData::IX_COUNT];
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, offset, size;
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    headerSize = udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (pErrorCode == NULL || U_FAILURE(*pErrorCode)) return 0;
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo = (const UDataInfo *)((const char *)inData + 4);
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!(pInfo->dataFormat[0] == 0x44 &&
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->dataFormat[1] == 0x69 &&
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->dataFormat[2] == 0x63 &&
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->dataFormat[3] == 0x74 &&
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->formatVersion[0] == 1)) {
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "udict_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as dictionary data\n",
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], pInfo->dataFormat[3], pInfo->formatVersion[0]);
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode = U_UNSUPPORTED_ERROR;
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inBytes = (const uint8_t *)inData + headerSize;
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    outBytes = (uint8_t *)outData + headerSize;
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inIndexes = (const int32_t *)inBytes;
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (length >= 0) {
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        length -= headerSize;
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (length < (int32_t)(sizeof(indexes))) {
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "udict_swap(): too few bytes (%d after header) for dictionary data\n", length);
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR;
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (i = 0; i < DictionaryData::IX_COUNT; i++) {
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[i] = udata_readInt32(ds, inIndexes[i]);
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    size = indexes[DictionaryData::IX_TOTAL_SIZE];
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (length >= 0) {
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (length < size) {
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "udict_swap(): too few bytes (%d after header) for all of dictionary data\n", length);
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR;
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (inBytes != outBytes) {
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(outBytes, inBytes, size);
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset = 0;
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inBytes, sizeof(indexes), outBytes, pErrorCode);
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset = (int32_t)sizeof(indexes);
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t trieType = indexes[DictionaryData::IX_TRIE_TYPE] & DictionaryData::TRIE_TYPE_MASK;
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t nextOffset = indexes[DictionaryData::IX_RESERVED1_OFFSET];
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (trieType == DictionaryData::TRIE_TYPE_UCHARS) {
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ds->swapArray16(ds, inBytes + offset, nextOffset - offset, outBytes + offset, pErrorCode);
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (trieType == DictionaryData::TRIE_TYPE_BYTES) {
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // nothing to do
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "udict_swap(): unknown trie type!\n");
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode = U_UNSUPPORTED_ERROR;
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // these next two sections are empty in the current format,
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // but may be used later.
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset = nextOffset;
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        nextOffset = indexes[DictionaryData::IX_RESERVED2_OFFSET];
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset = nextOffset;
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        nextOffset = indexes[DictionaryData::IX_TOTAL_SIZE];
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset = nextOffset;
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize + size;
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
234