16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 2005-2012, International Business Machines
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Corporation and others.  All Rights Reserved.
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   file name:  swapimpl.cpp
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   encoding:   US-ASCII
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   tab size:   8 (not used)
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   indentation:4
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created on: 2005may05
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created by: Markus W. Scherer
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Data file swapping functions moved here from the common library
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   because some data is hardcoded in ICU4C and needs not be swapped any more.
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Moving the functions here simplifies testing (for code coverage) because
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   we need not jump through hoops (like adding snapshots of these files
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   to testdata).
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   The declarations for these functions remain in the internal header files
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   in icu/source/common/
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/putil.h"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/udata.h"
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Explicit include statement for std_string.h is needed
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for compilation on certain platforms. (e.g. AIX/VACPP)
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/std_string.h"
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h"
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uinvchar.h"
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h"
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uarrsort.h"
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucmndata.h"
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "udataswp.h"
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* swapping implementations in common */
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresdata.h"
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_io.h"
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uprops.h"
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucase.h"
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ubidi_props.h"
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucol_swp.h"
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_bld.h"
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unormimp.h"
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "normalizer2impl.h"
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "sprpimpl.h"
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "propname.h"
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "rbbidata.h"
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utrie2.h"
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "dictionarydata.h"
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* swapping implementations in i18n */
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_NORMALIZATION
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uspoof_impl.h"
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_USE
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* definitions */
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Unicode property (value) aliases data swapping --------------------------- */
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupname_swap(const UDataSwapper *ds,
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const void *inData, int32_t length, void *outData,
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UErrorCode *pErrorCode) {
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* udata_swapDataHeader checks the arguments */
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* check data format and format version */
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo=
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        reinterpret_cast<const UDataInfo *>(
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            static_cast<const char *>(inData)+4);
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(!(
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[0]==0x70 &&   /* dataFormat="pnam" */
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[1]==0x6e &&
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[2]==0x61 &&
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[3]==0x6d &&
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->formatVersion[0]==2
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    )) {
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "upname_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as pnames.icu\n",
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1],
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[2], pInfo->dataFormat[3],
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->formatVersion[0]);
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *inBytes=static_cast<const uint8_t *>(inData)+headerSize;
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t *outBytes=static_cast<uint8_t *>(outData)+headerSize;
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        length-=headerSize;
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // formatVersion 2 initially has indexes[8], 32 bytes.
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<32) {
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "upname_swap(): too few bytes (%d after header) for pnames.icu\n",
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             (int)length);
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const int32_t *inIndexes=reinterpret_cast<const int32_t *>(inBytes);
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t totalSize=udata_readInt32(ds, inIndexes[PropNameData::IX_TOTAL_SIZE]);
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<totalSize) {
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "upname_swap(): too few bytes (%d after header, should be %d) "
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             "for pnames.icu\n",
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             (int)length, (int)totalSize);
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t numBytesIndexesAndValueMaps=
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_readInt32(ds, inIndexes[PropNameData::IX_BYTE_TRIES_OFFSET]);
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Swap the indexes[] and the valueMaps[].
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inBytes, numBytesIndexesAndValueMaps, outBytes, pErrorCode);
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Copy the rest of the data.
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(inBytes!=outBytes) {
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(outBytes+numBytesIndexesAndValueMaps,
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        inBytes+numBytesIndexesAndValueMaps,
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        totalSize-numBytesIndexesAndValueMaps);
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // We need not swap anything else:
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        //
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // The ByteTries are already byte-serialized, and are fixed on ASCII.
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // (On an EBCDIC machine, the input string is converted to lowercase ASCII
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // while matching.)
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        //
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // The name groups are mostly invariant characters, but since we only
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // generate, and keep in subversion, ASCII versions of pnames.icu,
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // and since only ICU4J uses the pnames.icu data file
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // (the data is hardcoded in ICU4C) and ICU4J uses ASCII data files,
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // we just copy those bytes too.
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize+totalSize;
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Unicode properties data swapping ----------------------------------------- */
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguprops_swap(const UDataSwapper *ds,
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const void *inData, int32_t length, void *outData,
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UErrorCode *pErrorCode) {
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize, i;
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t dataIndexes[UPROPS_INDEX_COUNT];
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const int32_t *inData32;
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* udata_swapDataHeader checks the arguments */
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* check data format and format version */
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo=(const UDataInfo *)((const char *)inData+4);
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(!(
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[0]==0x55 &&   /* dataFormat="UPro" */
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[1]==0x50 &&
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[2]==0x72 &&
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[3]==0x6f &&
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        (3<=pInfo->formatVersion[0] && pInfo->formatVersion[0]<=7) &&
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        (pInfo->formatVersion[0]>=7 ||
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (pInfo->formatVersion[2]==UTRIE_SHIFT &&
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT))
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    )) {
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "uprops_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not a Unicode properties file\n",
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1],
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[2], pInfo->dataFormat[3],
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->formatVersion[0]);
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* the properties file must contain at least the indexes array */
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0 && (length-headerSize)<(int32_t)sizeof(dataIndexes)) {
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "uprops_swap(): too few bytes (%d after header) for a Unicode properties file\n",
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         length-headerSize);
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* read the indexes */
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inData32=(const int32_t *)((const char *)inData+headerSize);
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<UPROPS_INDEX_COUNT; ++i) {
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        dataIndexes[i]=udata_readInt32(ds, inData32[i]);
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * comments are copied from the data format description in genprops/store.c
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * indexes[] constants are in uprops.h
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t dataTop;
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t *outData32;
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * In formatVersion 7, UPROPS_DATA_TOP_INDEX has the post-header data size.
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * In earlier formatVersions, it is 0 and a lower dataIndexes entry
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * has the top of the last item.
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for(i=UPROPS_DATA_TOP_INDEX; i>0 && (dataTop=dataIndexes[i])==0; --i) {}
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((length-headerSize)<(4*dataTop)) {
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "uprops_swap(): too few bytes (%d after header) for a Unicode properties file\n",
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length-headerSize);
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        outData32=(int32_t *)((char *)outData+headerSize);
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* copy everything for inaccessible data (padding) */
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(inData32!=outData32) {
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(outData32, inData32, 4*dataTop);
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the indexes[16] */
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inData32, 4*UPROPS_INDEX_COUNT, outData32, pErrorCode);
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * swap the main properties UTrie
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * PT serialized properties trie, see utrie.h (byte size: 4*(i0-16))
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        utrie2_swapAnyVersion(ds,
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            inData32+UPROPS_INDEX_COUNT,
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            4*(dataIndexes[UPROPS_PROPS32_INDEX]-UPROPS_INDEX_COUNT),
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            outData32+UPROPS_INDEX_COUNT,
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pErrorCode);
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * swap the properties and exceptions words
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * P  const uint32_t props32[i1-i0];
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * E  const uint32_t exceptions[i2-i1];
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds,
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            inData32+dataIndexes[UPROPS_PROPS32_INDEX],
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            4*(dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX]-dataIndexes[UPROPS_PROPS32_INDEX]),
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            outData32+dataIndexes[UPROPS_PROPS32_INDEX],
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pErrorCode);
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * swap the UChars
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * U  const UChar uchars[2*(i3-i2)];
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray16(ds,
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            inData32+dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX],
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            4*(dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX]-dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX]),
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            outData32+dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX],
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pErrorCode);
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * swap the additional UTrie
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * i3 additionalTrieIndex; -- 32-bit unit index to the additional trie for more properties
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        utrie2_swapAnyVersion(ds,
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            inData32+dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX],
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            4*(dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX]-dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX]),
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            outData32+dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX],
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pErrorCode);
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * swap the properties vectors
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * PV const uint32_t propsVectors[(i6-i4)/i5][i5]==uint32_t propsVectors[i6-i4];
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds,
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            inData32+dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX],
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            4*(dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX]-dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX]),
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            outData32+dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX],
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pErrorCode);
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // swap the Script_Extensions data
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // SCX const uint16_t scriptExtensions[2*(i7-i6)];
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray16(ds,
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            inData32+dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX],
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            4*(dataIndexes[UPROPS_RESERVED_INDEX_7]-dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX]),
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            outData32+dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX],
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pErrorCode);
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* i7 reservedIndex7; -- 32-bit unit index to the top of the Script_Extensions data */
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize+4*dataIndexes[UPROPS_RESERVED_INDEX_7];
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Unicode case mapping data swapping --------------------------------------- */
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucase_swap(const UDataSwapper *ds,
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           const void *inData, int32_t length, void *outData,
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *pErrorCode) {
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize;
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *inBytes;
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t *outBytes;
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const int32_t *inIndexes;
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t indexes[16];
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, offset, count, size;
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* udata_swapDataHeader checks the arguments */
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* check data format and format version */
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo=(const UDataInfo *)((const char *)inData+4);
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(!(
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[0]==UCASE_FMT_0 &&    /* dataFormat="cAsE" */
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[1]==UCASE_FMT_1 &&
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[2]==UCASE_FMT_2 &&
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[3]==UCASE_FMT_3 &&
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((pInfo->formatVersion[0]==1 &&
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->formatVersion[2]==UTRIE_SHIFT &&
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT) ||
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         pInfo->formatVersion[0]==2 || pInfo->formatVersion[0]==3)
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    )) {
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "ucase_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as case mapping data\n",
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1],
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[2], pInfo->dataFormat[3],
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->formatVersion[0]);
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inBytes=(const uint8_t *)inData+headerSize;
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    outBytes=(uint8_t *)outData+headerSize;
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inIndexes=(const int32_t *)inBytes;
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        length-=headerSize;
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<16*4) {
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "ucase_swap(): too few bytes (%d after header) for case mapping data\n",
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length);
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* read the first 16 indexes (ICU 3.2/format version 1: UCASE_IX_TOP==16, might grow) */
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<16; ++i) {
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[i]=udata_readInt32(ds, inIndexes[i]);
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* get the total length of the data */
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    size=indexes[UCASE_IX_LENGTH];
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<size) {
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "ucase_swap(): too few bytes (%d after header) for all of case mapping data\n",
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length);
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* copy the data for inaccessible bytes */
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(inBytes!=outBytes) {
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(outBytes, inBytes, size);
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=0;
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the int32_t indexes[] */
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[UCASE_IX_INDEX_TOP]*4;
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode);
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the UTrie */
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[UCASE_IX_TRIE_SIZE];
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        utrie2_swapAnyVersion(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the uint16_t exceptions[] and unfold[] */
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=(indexes[UCASE_IX_EXC_LENGTH]+indexes[UCASE_IX_UNFOLD_LENGTH])*2;
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_ASSERT(offset==size);
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize+size;
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Unicode bidi/shaping data swapping --------------------------------------- */
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgubidi_swap(const UDataSwapper *ds,
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           const void *inData, int32_t length, void *outData,
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *pErrorCode) {
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize;
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *inBytes;
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t *outBytes;
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const int32_t *inIndexes;
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t indexes[16];
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, offset, count, size;
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* udata_swapDataHeader checks the arguments */
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* check data format and format version */
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo=(const UDataInfo *)((const char *)inData+4);
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(!(
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[0]==UBIDI_FMT_0 &&    /* dataFormat="BiDi" */
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[1]==UBIDI_FMT_1 &&
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[2]==UBIDI_FMT_2 &&
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[3]==UBIDI_FMT_3 &&
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((pInfo->formatVersion[0]==1 &&
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->formatVersion[2]==UTRIE_SHIFT &&
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT) ||
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         pInfo->formatVersion[0]==2)
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    )) {
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "ubidi_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as bidi/shaping data\n",
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1],
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[2], pInfo->dataFormat[3],
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->formatVersion[0]);
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inBytes=(const uint8_t *)inData+headerSize;
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    outBytes=(uint8_t *)outData+headerSize;
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inIndexes=(const int32_t *)inBytes;
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        length-=headerSize;
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<16*4) {
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "ubidi_swap(): too few bytes (%d after header) for bidi/shaping data\n",
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length);
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* read the first 16 indexes (ICU 3.4/format version 1: UBIDI_IX_TOP==16, might grow) */
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<16; ++i) {
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[i]=udata_readInt32(ds, inIndexes[i]);
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* get the total length of the data */
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    size=indexes[UBIDI_IX_LENGTH];
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<size) {
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "ubidi_swap(): too few bytes (%d after header) for all of bidi/shaping data\n",
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length);
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* copy the data for inaccessible bytes */
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(inBytes!=outBytes) {
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(outBytes, inBytes, size);
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=0;
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the int32_t indexes[] */
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[UBIDI_IX_INDEX_TOP]*4;
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode);
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the UTrie */
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[UBIDI_IX_TRIE_SIZE];
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        utrie2_swapAnyVersion(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the uint32_t mirrors[] */
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[UBIDI_IX_MIRROR_LENGTH]*4;
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* just skip the uint8_t jgArray[] */
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[UBIDI_IX_JG_LIMIT]-indexes[UBIDI_IX_JG_START];
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_ASSERT(offset==size);
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize+size;
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Unicode normalization data swapping -------------------------------------- */
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_NORMALIZATION
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgunorm_swap(const UDataSwapper *ds,
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           const void *inData, int32_t length, void *outData,
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *pErrorCode) {
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize;
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *inBytes;
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t *outBytes;
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const int32_t *inIndexes;
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t indexes[32];
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, offset, count, size;
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* udata_swapDataHeader checks the arguments */
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* check data format and format version */
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo=(const UDataInfo *)((const char *)inData+4);
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(!(
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[0]==0x4e &&   /* dataFormat="Norm" */
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[1]==0x6f &&
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[2]==0x72 &&
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[3]==0x6d &&
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->formatVersion[0]==2
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    )) {
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "unorm_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as unorm.icu\n",
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1],
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[2], pInfo->dataFormat[3],
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->formatVersion[0]);
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inBytes=(const uint8_t *)inData+headerSize;
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    outBytes=(uint8_t *)outData+headerSize;
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inIndexes=(const int32_t *)inBytes;
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        length-=headerSize;
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<32*4) {
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "unorm_swap(): too few bytes (%d after header) for unorm.icu\n",
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length);
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* read the first 32 indexes (ICU 2.8/format version 2.2: _NORM_INDEX_TOP==32, might grow) */
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<32; ++i) {
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[i]=udata_readInt32(ds, inIndexes[i]);
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* calculate the total length of the data */
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    size=
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        32*4+ /* size of indexes[] */
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[_NORM_INDEX_TRIE_SIZE]+
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[_NORM_INDEX_UCHAR_COUNT]*2+
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[_NORM_INDEX_COMBINE_DATA_COUNT]*2+
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[_NORM_INDEX_FCD_TRIE_SIZE]+
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[_NORM_INDEX_AUX_TRIE_SIZE]+
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indexes[_NORM_INDEX_CANON_SET_COUNT]*2;
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<size) {
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "unorm_swap(): too few bytes (%d after header) for all of unorm.icu\n",
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length);
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* copy the data for inaccessible bytes */
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(inBytes!=outBytes) {
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(outBytes, inBytes, size);
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=0;
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the indexes[] */
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=32*4;
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode);
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the main UTrie */
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[_NORM_INDEX_TRIE_SIZE];
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the uint16_t extraData[] and the uint16_t combiningTable[] */
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=(indexes[_NORM_INDEX_UCHAR_COUNT]+indexes[_NORM_INDEX_COMBINE_DATA_COUNT])*2;
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the FCD UTrie */
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[_NORM_INDEX_FCD_TRIE_SIZE];
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(count!=0) {
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            offset+=count;
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the aux UTrie */
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[_NORM_INDEX_AUX_TRIE_SIZE];
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(count!=0) {
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            offset+=count;
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* swap the uint16_t combiningTable[] */
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count=indexes[_NORM_INDEX_CANON_SET_COUNT]*2;
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset+=count;
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize+size;
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Swap 'Test' data from gentest */
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtest_swap(const UDataSwapper *ds,
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           const void *inData, int32_t length, void *outData,
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *pErrorCode) {
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t headerSize;
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *inBytes;
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t *outBytes;
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offset;
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* udata_swapDataHeader checks the arguments */
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "test_swap(): data header swap failed %s\n", pErrorCode != NULL ? u_errorName(*pErrorCode) : "pErrorCode is NULL");
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* check data format and format version */
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo=(const UDataInfo *)((const char *)inData+4);
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(!(
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[0]==0x54 &&   /* dataFormat="Norm" */
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[1]==0x65 &&
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[2]==0x73 &&
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->dataFormat[3]==0x74 &&
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pInfo->formatVersion[0]==1
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    )) {
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udata_printError(ds, "test_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as testdata\n",
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[0], pInfo->dataFormat[1],
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->dataFormat[2], pInfo->dataFormat[3],
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         pInfo->formatVersion[0]);
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inBytes=(const uint8_t *)inData+headerSize;
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    outBytes=(uint8_t *)outData+headerSize;
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t size16 = 2; // 16bit plus padding
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t sizeStr = 5; // 4 char inv-str plus null
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t size = size16 + sizeStr;
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length>=0) {
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(length<size) {
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            udata_printError(ds, "test_swap(): too few bytes (%d after header, wanted %d) for all of testdata\n",
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             length, size);
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	offset =0;
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	/* swap a 1 entry array */
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ds->swapArray16(ds, inBytes+offset, size16, outBytes+offset, pErrorCode);
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	offset+=size16;
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org	ds->swapInvChars(ds, inBytes+offset, sizeStr, outBytes+offset, pErrorCode);
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return headerSize+size;
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* swap any data (except a .dat package) ------------------------------------ */
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const struct {
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t dataFormat[4];
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDataSwapFn *swapFn;
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} swapFns[]={
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x52, 0x65, 0x73, 0x42 }, ures_swap },          /* dataFormat="ResB" */
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_LEGACY_CONVERSION
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x63, 0x6e, 0x76, 0x74 }, ucnv_swap },          /* dataFormat="cnvt" */
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_CONVERSION
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x43, 0x76, 0x41, 0x6c }, ucnv_swapAliases },   /* dataFormat="CvAl" */
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_IDNA
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x53, 0x50, 0x52, 0x50 }, usprep_swap },        /* dataFormat="SPRP" */
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* insert data formats here, descending by expected frequency of occurrence */
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x55, 0x50, 0x72, 0x6f }, uprops_swap },        /* dataFormat="UPro" */
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { UCASE_FMT_0, UCASE_FMT_1, UCASE_FMT_2, UCASE_FMT_3 },
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  ucase_swap },         /* dataFormat="cAsE" */
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { UBIDI_FMT_0, UBIDI_FMT_1, UBIDI_FMT_2, UBIDI_FMT_3 },
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  ubidi_swap },         /* dataFormat="BiDi" */
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_NORMALIZATION
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x4e, 0x6f, 0x72, 0x6d }, unorm_swap },         /* dataFormat="Norm" */
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x4e, 0x72, 0x6d, 0x32 }, unorm2_swap },        /* dataFormat="Nrm2" */
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_COLLATION
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x55, 0x43, 0x6f, 0x6c }, ucol_swap },          /* dataFormat="UCol" */
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x49, 0x6e, 0x76, 0x43 }, ucol_swapInverseUCA },/* dataFormat="InvC" */
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_BREAK_ITERATION
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x42, 0x72, 0x6b, 0x20 }, ubrk_swap },          /* dataFormat="Brk " */
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x44, 0x69, 0x63, 0x74 }, udict_swap },         /* dataFormat="Dict" */
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x70, 0x6e, 0x61, 0x6d }, upname_swap },        /* dataFormat="pnam" */
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x75, 0x6e, 0x61, 0x6d }, uchar_swapNames },    /* dataFormat="unam" */
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_NORMALIZATION
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x43, 0x66, 0x75, 0x20 }, uspoof_swap },         /* dataFormat="Cfu " */
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { { 0x54, 0x65, 0x73, 0x74 }, test_swap }            /* dataFormat="Test" */
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgudata_swap(const UDataSwapper *ds,
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           const void *inData, int32_t length, void *outData,
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *pErrorCode) {
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    char dataFormatChars[4];
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UDataInfo *pInfo;
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, swappedLength;
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Preflight the header first; checks for illegal arguments, too.
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Do not swap the header right away because the format-specific swapper
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * will swap it, get the headerSize again, and also use the header
7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * information. Otherwise we would have to pass some of the information
7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * and not be able to use the UDataSwapFn signature.
7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udata_swapDataHeader(ds, inData, -1, NULL, pErrorCode);
7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * If we wanted udata_swap() to also handle non-loadable data like a UTrie,
7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * then we could check here for further known magic values and structures.
7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*pErrorCode)) {
7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0; /* the data format was not recognized */
7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pInfo=(const UDataInfo *)((const char *)inData+4);
7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* convert the data format from ASCII to Unicode to the system charset */
7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar u[4]={
7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             pInfo->dataFormat[0], pInfo->dataFormat[1],
7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             pInfo->dataFormat[2], pInfo->dataFormat[3]
7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        };
7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(uprv_isInvariantUString(u, 4)) {
7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            u_UCharsToChars(u, dataFormatChars, 4);
7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            dataFormatChars[0]=dataFormatChars[1]=dataFormatChars[2]=dataFormatChars[3]='?';
7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* dispatch to the swap function for the dataFormat */
7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(swapFns); ++i) {
7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(0==memcmp(swapFns[i].dataFormat, pInfo->dataFormat, 4)) {
7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            swappedLength=swapFns[i].swapFn(ds, inData, length, outData, pErrorCode);
7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(U_FAILURE(*pErrorCode)) {
7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                udata_printError(ds, "udata_swap(): failure swapping data format %02x.%02x.%02x.%02x (\"%c%c%c%c\") - %s\n",
7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 pInfo->dataFormat[0], pInfo->dataFormat[1],
8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 pInfo->dataFormat[2], pInfo->dataFormat[3],
8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 dataFormatChars[0], dataFormatChars[1],
8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 dataFormatChars[2], dataFormatChars[3],
8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 u_errorName(*pErrorCode));
8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else if(swappedLength<(length-15)) {
8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* swapped less than expected */
8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                udata_printError(ds, "udata_swap() warning: swapped only %d out of %d bytes - data format %02x.%02x.%02x.%02x (\"%c%c%c%c\")\n",
8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 swappedLength, length,
8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 pInfo->dataFormat[0], pInfo->dataFormat[1],
8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 pInfo->dataFormat[2], pInfo->dataFormat[3],
8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 dataFormatChars[0], dataFormatChars[1],
8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 dataFormatChars[2], dataFormatChars[3],
8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 u_errorName(*pErrorCode));
8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return swappedLength;
8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* the dataFormat was not recognized */
8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udata_printError(ds, "udata_swap(): unknown data format %02x.%02x.%02x.%02x (\"%c%c%c%c\")\n",
8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     pInfo->dataFormat[0], pInfo->dataFormat[1],
8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     pInfo->dataFormat[2], pInfo->dataFormat[3],
8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     dataFormatChars[0], dataFormatChars[1],
8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     dataFormatChars[2], dataFormatChars[3]);
8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *pErrorCode=U_UNSUPPORTED_ERROR;
8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
829