1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
4103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius*   Copyright (C) 2005-2012, International Business Machines
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   file name:  swapimpl.cpp
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   encoding:   US-ASCII
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   tab size:   8 (not used)
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   indentation:4
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   created on: 2005may05
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   created by: Markus W. Scherer
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Data file swapping functions moved here from the common library
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   because some data is hardcoded in ICU4C and needs not be swapped any more.
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Moving the functions here simplifies testing (for code coverage) because
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   we need not jump through hoops (like adding snapshots of these files
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   to testdata).
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   The declarations for these functions remain in the internal header files
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   in icu/source/common/
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h"
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h"
29b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
30b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* Explicit include statement for std_string.h is needed
31b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * for compilation on certain platforms. (e.g. AIX/VACPP)
32b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
33b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/std_string.h"
34b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uinvchar.h"
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h"
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uarrsort.h"
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucmndata.h"
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "udataswp.h"
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* swapping implementations in common */
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresdata.h"
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_io.h"
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uprops.h"
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucase.h"
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ubidi_props.h"
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_swp.h"
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_bld.h"
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unormimp.h"
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "normalizer2impl.h"
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "sprpimpl.h"
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "propname.h"
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "rbbidata.h"
5727f654740f2a26ad62a5c155af9199af9e69b889claireho#include "utrie2.h"
5854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "dictionarydata.h"
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* swapping implementations in i18n */
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if !UCONFIG_NO_NORMALIZATION
63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "uspoof_impl.h"
64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
66103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_NAMESPACE_USE
67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* definitions */
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* Unicode property (value) aliases data swapping --------------------------- */
73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV
75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoupname_swap(const UDataSwapper *ds,
76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            const void *inData, int32_t length, void *outData,
77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UErrorCode *pErrorCode) {
78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    /* udata_swapDataHeader checks the arguments */
79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return 0;
82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    /* check data format and format version */
85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UDataInfo *pInfo=
86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        reinterpret_cast<const UDataInfo *>(
8754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            static_cast<const char *>(inData)+4);
88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(!(
89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pInfo->dataFormat[0]==0x70 &&   /* dataFormat="pnam" */
90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pInfo->dataFormat[1]==0x6e &&
91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pInfo->dataFormat[2]==0x61 &&
92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pInfo->dataFormat[3]==0x6d &&
93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pInfo->formatVersion[0]==2
94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    )) {
95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        udata_printError(ds, "upname_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as pnames.icu\n",
96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                         pInfo->dataFormat[0], pInfo->dataFormat[1],
97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                         pInfo->dataFormat[2], pInfo->dataFormat[3],
98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                         pInfo->formatVersion[0]);
99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        *pErrorCode=U_UNSUPPORTED_ERROR;
100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return 0;
101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
10354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    const uint8_t *inBytes=static_cast<const uint8_t *>(inData)+headerSize;
10454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    uint8_t *outBytes=static_cast<uint8_t *>(outData)+headerSize;
105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(length>=0) {
107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        length-=headerSize;
108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // formatVersion 2 initially has indexes[8], 32 bytes.
109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(length<32) {
110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            udata_printError(ds, "upname_swap(): too few bytes (%d after header) for pnames.icu\n",
111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             (int)length);
112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return 0;
114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const int32_t *inIndexes=reinterpret_cast<const int32_t *>(inBytes);
118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t totalSize=udata_readInt32(ds, inIndexes[PropNameData::IX_TOTAL_SIZE]);
119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(length>=0) {
120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(length<totalSize) {
121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            udata_printError(ds, "upname_swap(): too few bytes (%d after header, should be %d) "
122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             "for pnames.icu\n",
123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                             (int)length, (int)totalSize);
124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return 0;
126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t numBytesIndexesAndValueMaps=
129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            udata_readInt32(ds, inIndexes[PropNameData::IX_BYTE_TRIES_OFFSET]);
130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // Swap the indexes[] and the valueMaps[].
132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        ds->swapArray32(ds, inBytes, numBytesIndexesAndValueMaps, outBytes, pErrorCode);
133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // Copy the rest of the data.
135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(inBytes!=outBytes) {
136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            uprv_memcpy(outBytes+numBytesIndexesAndValueMaps,
137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        inBytes+numBytesIndexesAndValueMaps,
138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        totalSize-numBytesIndexesAndValueMaps);
139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // We need not swap anything else:
142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        //
143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // The ByteTries are already byte-serialized, and are fixed on ASCII.
144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // (On an EBCDIC machine, the input string is converted to lowercase ASCII
145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // while matching.)
146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        //
147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // The name groups are mostly invariant characters, but since we only
148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // generate, and keep in subversion, ASCII versions of pnames.icu,
149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // and since only ICU4J uses the pnames.icu data file
150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // (the data is hardcoded in ICU4C) and ICU4J uses ASCII data files,
151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // we just copy those bytes too.
152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return headerSize+totalSize;
155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Unicode properties data swapping ----------------------------------------- */
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprops_swap(const UDataSwapper *ds,
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const void *inData, int32_t length, void *outData,
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UErrorCode *pErrorCode) {
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UDataInfo *pInfo;
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t headerSize, i;
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t dataIndexes[UPROPS_INDEX_COUNT];
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t *inData32;
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* udata_swapDataHeader checks the arguments */
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* check data format and format version */
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pInfo=(const UDataInfo *)((const char *)inData+4);
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(!(
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[0]==0x55 &&   /* dataFormat="UPro" */
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[1]==0x50 &&
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[2]==0x72 &&
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[3]==0x6f &&
18227f654740f2a26ad62a5c155af9199af9e69b889claireho        (3<=pInfo->formatVersion[0] && pInfo->formatVersion[0]<=7) &&
18327f654740f2a26ad62a5c155af9199af9e69b889claireho        (pInfo->formatVersion[0]>=7 ||
18427f654740f2a26ad62a5c155af9199af9e69b889claireho            (pInfo->formatVersion[2]==UTRIE_SHIFT &&
18527f654740f2a26ad62a5c155af9199af9e69b889claireho             pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT))
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    )) {
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_printError(ds, "uprops_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not a Unicode properties file\n",
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[0], pInfo->dataFormat[1],
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[2], pInfo->dataFormat[3],
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->formatVersion[0]);
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_UNSUPPORTED_ERROR;
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* the properties file must contain at least the indexes array */
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0 && (length-headerSize)<(int32_t)sizeof(dataIndexes)) {
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_printError(ds, "uprops_swap(): too few bytes (%d after header) for a Unicode properties file\n",
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         length-headerSize);
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* read the indexes */
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inData32=(const int32_t *)((const char *)inData+headerSize);
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(i=0; i<UPROPS_INDEX_COUNT; ++i) {
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dataIndexes[i]=udata_readInt32(ds, inData32[i]);
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * comments are copied from the data format description in genprops/store.c
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * indexes[] constants are in uprops.h
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
21327f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t dataTop;
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t *outData32;
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
21727f654740f2a26ad62a5c155af9199af9e69b889claireho        /*
21827f654740f2a26ad62a5c155af9199af9e69b889claireho         * In formatVersion 7, UPROPS_DATA_TOP_INDEX has the post-header data size.
21927f654740f2a26ad62a5c155af9199af9e69b889claireho         * In earlier formatVersions, it is 0 and a lower dataIndexes entry
22027f654740f2a26ad62a5c155af9199af9e69b889claireho         * has the top of the last item.
22127f654740f2a26ad62a5c155af9199af9e69b889claireho         */
22227f654740f2a26ad62a5c155af9199af9e69b889claireho        for(i=UPROPS_DATA_TOP_INDEX; i>0 && (dataTop=dataIndexes[i])==0; --i) {}
22327f654740f2a26ad62a5c155af9199af9e69b889claireho
22427f654740f2a26ad62a5c155af9199af9e69b889claireho        if((length-headerSize)<(4*dataTop)) {
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "uprops_swap(): too few bytes (%d after header) for a Unicode properties file\n",
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length-headerSize);
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        outData32=(int32_t *)((char *)outData+headerSize);
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* copy everything for inaccessible data (padding) */
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(inData32!=outData32) {
23527f654740f2a26ad62a5c155af9199af9e69b889claireho            uprv_memcpy(outData32, inData32, 4*dataTop);
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the indexes[16] */
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds, inData32, 4*UPROPS_INDEX_COUNT, outData32, pErrorCode);
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * swap the main properties UTrie
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * PT serialized properties trie, see utrie.h (byte size: 4*(i0-16))
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
24527f654740f2a26ad62a5c155af9199af9e69b889claireho        utrie2_swapAnyVersion(ds,
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            inData32+UPROPS_INDEX_COUNT,
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            4*(dataIndexes[UPROPS_PROPS32_INDEX]-UPROPS_INDEX_COUNT),
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            outData32+UPROPS_INDEX_COUNT,
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pErrorCode);
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * swap the properties and exceptions words
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * P  const uint32_t props32[i1-i0];
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * E  const uint32_t exceptions[i2-i1];
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds,
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            inData32+dataIndexes[UPROPS_PROPS32_INDEX],
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            4*(dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX]-dataIndexes[UPROPS_PROPS32_INDEX]),
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            outData32+dataIndexes[UPROPS_PROPS32_INDEX],
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pErrorCode);
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * swap the UChars
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * U  const UChar uchars[2*(i3-i2)];
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray16(ds,
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            inData32+dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX],
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            4*(dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX]-dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX]),
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            outData32+dataIndexes[UPROPS_EXCEPTIONS_TOP_INDEX],
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pErrorCode);
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * swap the additional UTrie
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * i3 additionalTrieIndex; -- 32-bit unit index to the additional trie for more properties
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
27627f654740f2a26ad62a5c155af9199af9e69b889claireho        utrie2_swapAnyVersion(ds,
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            inData32+dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX],
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            4*(dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX]-dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX]),
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            outData32+dataIndexes[UPROPS_ADDITIONAL_TRIE_INDEX],
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pErrorCode);
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * swap the properties vectors
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * PV const uint32_t propsVectors[(i6-i4)/i5][i5]==uint32_t propsVectors[i6-i4];
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds,
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            inData32+dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX],
28827f654740f2a26ad62a5c155af9199af9e69b889claireho            4*(dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX]-dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX]),
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            outData32+dataIndexes[UPROPS_ADDITIONAL_VECTORS_INDEX],
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pErrorCode);
29127f654740f2a26ad62a5c155af9199af9e69b889claireho
29227f654740f2a26ad62a5c155af9199af9e69b889claireho        // swap the Script_Extensions data
29327f654740f2a26ad62a5c155af9199af9e69b889claireho        // SCX const uint16_t scriptExtensions[2*(i7-i6)];
29427f654740f2a26ad62a5c155af9199af9e69b889claireho        ds->swapArray16(ds,
29527f654740f2a26ad62a5c155af9199af9e69b889claireho            inData32+dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX],
29627f654740f2a26ad62a5c155af9199af9e69b889claireho            4*(dataIndexes[UPROPS_RESERVED_INDEX_7]-dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX]),
29727f654740f2a26ad62a5c155af9199af9e69b889claireho            outData32+dataIndexes[UPROPS_SCRIPT_EXTENSIONS_INDEX],
29827f654740f2a26ad62a5c155af9199af9e69b889claireho            pErrorCode);
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
30127f654740f2a26ad62a5c155af9199af9e69b889claireho    /* i7 reservedIndex7; -- 32-bit unit index to the top of the Script_Extensions data */
30227f654740f2a26ad62a5c155af9199af9e69b889claireho    return headerSize+4*dataIndexes[UPROPS_RESERVED_INDEX_7];
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Unicode case mapping data swapping --------------------------------------- */
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucase_swap(const UDataSwapper *ds,
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           const void *inData, int32_t length, void *outData,
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           UErrorCode *pErrorCode) {
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UDataInfo *pInfo;
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t headerSize;
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const uint8_t *inBytes;
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t *outBytes;
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t *inIndexes;
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t indexes[16];
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i, offset, count, size;
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* udata_swapDataHeader checks the arguments */
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* check data format and format version */
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pInfo=(const UDataInfo *)((const char *)inData+4);
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(!(
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[0]==UCASE_FMT_0 &&    /* dataFormat="cAsE" */
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[1]==UCASE_FMT_1 &&
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[2]==UCASE_FMT_2 &&
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[3]==UCASE_FMT_3 &&
33527f654740f2a26ad62a5c155af9199af9e69b889claireho        ((pInfo->formatVersion[0]==1 &&
33627f654740f2a26ad62a5c155af9199af9e69b889claireho          pInfo->formatVersion[2]==UTRIE_SHIFT &&
33727f654740f2a26ad62a5c155af9199af9e69b889claireho          pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT) ||
338103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius         pInfo->formatVersion[0]==2 || pInfo->formatVersion[0]==3)
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    )) {
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_printError(ds, "ucase_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as case mapping data\n",
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[0], pInfo->dataFormat[1],
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[2], pInfo->dataFormat[3],
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->formatVersion[0]);
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_UNSUPPORTED_ERROR;
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inBytes=(const uint8_t *)inData+headerSize;
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    outBytes=(uint8_t *)outData+headerSize;
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inIndexes=(const int32_t *)inBytes;
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        length-=headerSize;
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(length<16*4) {
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "ucase_swap(): too few bytes (%d after header) for case mapping data\n",
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length);
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* read the first 16 indexes (ICU 3.2/format version 1: UCASE_IX_TOP==16, might grow) */
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(i=0; i<16; ++i) {
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[i]=udata_readInt32(ds, inIndexes[i]);
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* get the total length of the data */
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    size=indexes[UCASE_IX_LENGTH];
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(length<size) {
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "ucase_swap(): too few bytes (%d after header) for all of case mapping data\n",
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length);
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* copy the data for inaccessible bytes */
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(inBytes!=outBytes) {
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_memcpy(outBytes, inBytes, size);
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset=0;
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the int32_t indexes[] */
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[UCASE_IX_INDEX_TOP]*4;
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode);
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the UTrie */
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[UCASE_IX_TRIE_SIZE];
39327f654740f2a26ad62a5c155af9199af9e69b889claireho        utrie2_swapAnyVersion(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the uint16_t exceptions[] and unfold[] */
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=(indexes[UCASE_IX_EXC_LENGTH]+indexes[UCASE_IX_UNFOLD_LENGTH])*2;
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        U_ASSERT(offset==size);
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return headerSize+size;
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Unicode bidi/shaping data swapping --------------------------------------- */
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruubidi_swap(const UDataSwapper *ds,
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           const void *inData, int32_t length, void *outData,
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           UErrorCode *pErrorCode) {
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UDataInfo *pInfo;
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t headerSize;
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const uint8_t *inBytes;
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t *outBytes;
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t *inIndexes;
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t indexes[16];
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i, offset, count, size;
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* udata_swapDataHeader checks the arguments */
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* check data format and format version */
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pInfo=(const UDataInfo *)((const char *)inData+4);
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(!(
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[0]==UBIDI_FMT_0 &&    /* dataFormat="BiDi" */
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[1]==UBIDI_FMT_1 &&
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[2]==UBIDI_FMT_2 &&
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[3]==UBIDI_FMT_3 &&
43727f654740f2a26ad62a5c155af9199af9e69b889claireho        ((pInfo->formatVersion[0]==1 &&
43827f654740f2a26ad62a5c155af9199af9e69b889claireho          pInfo->formatVersion[2]==UTRIE_SHIFT &&
43927f654740f2a26ad62a5c155af9199af9e69b889claireho          pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT) ||
44027f654740f2a26ad62a5c155af9199af9e69b889claireho         pInfo->formatVersion[0]==2)
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    )) {
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_printError(ds, "ubidi_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as bidi/shaping data\n",
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[0], pInfo->dataFormat[1],
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[2], pInfo->dataFormat[3],
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->formatVersion[0]);
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_UNSUPPORTED_ERROR;
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inBytes=(const uint8_t *)inData+headerSize;
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    outBytes=(uint8_t *)outData+headerSize;
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inIndexes=(const int32_t *)inBytes;
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        length-=headerSize;
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(length<16*4) {
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "ubidi_swap(): too few bytes (%d after header) for bidi/shaping data\n",
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length);
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* read the first 16 indexes (ICU 3.4/format version 1: UBIDI_IX_TOP==16, might grow) */
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(i=0; i<16; ++i) {
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[i]=udata_readInt32(ds, inIndexes[i]);
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* get the total length of the data */
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    size=indexes[UBIDI_IX_LENGTH];
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(length<size) {
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "ubidi_swap(): too few bytes (%d after header) for all of bidi/shaping data\n",
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length);
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* copy the data for inaccessible bytes */
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(inBytes!=outBytes) {
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_memcpy(outBytes, inBytes, size);
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset=0;
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the int32_t indexes[] */
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[UBIDI_IX_INDEX_TOP]*4;
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode);
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the UTrie */
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[UBIDI_IX_TRIE_SIZE];
49527f654740f2a26ad62a5c155af9199af9e69b889claireho        utrie2_swapAnyVersion(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the uint32_t mirrors[] */
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[UBIDI_IX_MIRROR_LENGTH]*4;
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* just skip the uint8_t jgArray[] */
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[UBIDI_IX_JG_LIMIT]-indexes[UBIDI_IX_JG_START];
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        U_ASSERT(offset==size);
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return headerSize+size;
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Unicode normalization data swapping -------------------------------------- */
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_NORMALIZATION
516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruunorm_swap(const UDataSwapper *ds,
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           const void *inData, int32_t length, void *outData,
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           UErrorCode *pErrorCode) {
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UDataInfo *pInfo;
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t headerSize;
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const uint8_t *inBytes;
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t *outBytes;
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t *inIndexes;
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t indexes[32];
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i, offset, count, size;
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* udata_swapDataHeader checks the arguments */
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* check data format and format version */
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pInfo=(const UDataInfo *)((const char *)inData+4);
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(!(
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[0]==0x4e &&   /* dataFormat="Norm" */
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[1]==0x6f &&
543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[2]==0x72 &&
544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->dataFormat[3]==0x6d &&
545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pInfo->formatVersion[0]==2
546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    )) {
547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_printError(ds, "unorm_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as unorm.icu\n",
548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[0], pInfo->dataFormat[1],
549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->dataFormat[2], pInfo->dataFormat[3],
550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         pInfo->formatVersion[0]);
551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_UNSUPPORTED_ERROR;
552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inBytes=(const uint8_t *)inData+headerSize;
556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    outBytes=(uint8_t *)outData+headerSize;
557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inIndexes=(const int32_t *)inBytes;
559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        length-=headerSize;
562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(length<32*4) {
563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "unorm_swap(): too few bytes (%d after header) for unorm.icu\n",
564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length);
565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* read the first 32 indexes (ICU 2.8/format version 2.2: _NORM_INDEX_TOP==32, might grow) */
571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(i=0; i<32; ++i) {
572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[i]=udata_readInt32(ds, inIndexes[i]);
573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* calculate the total length of the data */
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    size=
577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        32*4+ /* size of indexes[] */
578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[_NORM_INDEX_TRIE_SIZE]+
579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[_NORM_INDEX_UCHAR_COUNT]*2+
580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[_NORM_INDEX_COMBINE_DATA_COUNT]*2+
581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[_NORM_INDEX_FCD_TRIE_SIZE]+
582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[_NORM_INDEX_AUX_TRIE_SIZE]+
583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[_NORM_INDEX_CANON_SET_COUNT]*2;
584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(length>=0) {
586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(length<size) {
587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_printError(ds, "unorm_swap(): too few bytes (%d after header) for all of unorm.icu\n",
588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             length);
589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* copy the data for inaccessible bytes */
594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(inBytes!=outBytes) {
595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_memcpy(outBytes, inBytes, size);
596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset=0;
599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the indexes[] */
601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=32*4;
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode);
603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the main UTrie */
606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[_NORM_INDEX_TRIE_SIZE];
607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the uint16_t extraData[] and the uint16_t combiningTable[] */
611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=(indexes[_NORM_INDEX_UCHAR_COUNT]+indexes[_NORM_INDEX_COMBINE_DATA_COUNT])*2;
612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the FCD UTrie */
616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[_NORM_INDEX_FCD_TRIE_SIZE];
617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(count!=0) {
618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            offset+=count;
620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the aux UTrie */
623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[_NORM_INDEX_AUX_TRIE_SIZE];
624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(count!=0) {
625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            offset+=count;
627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* swap the uint16_t combiningTable[] */
630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        count=indexes[_NORM_INDEX_CANON_SET_COUNT]*2;
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode);
632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        offset+=count;
633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return headerSize+size;
636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
640b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* Swap 'Test' data from gentest */
641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV
642b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querutest_swap(const UDataSwapper *ds,
643b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           const void *inData, int32_t length, void *outData,
644b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           UErrorCode *pErrorCode) {
645b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UDataInfo *pInfo;
646b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t headerSize;
647b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
648b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const uint8_t *inBytes;
649b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    uint8_t *outBytes;
650b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
65150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t offset;
652b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
653b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /* udata_swapDataHeader checks the arguments */
654b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
655b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
65654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        udata_printError(ds, "test_swap(): data header swap failed %s\n", pErrorCode != NULL ? u_errorName(*pErrorCode) : "pErrorCode is NULL");
657b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return 0;
658b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
659b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
660b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /* check data format and format version */
661b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    pInfo=(const UDataInfo *)((const char *)inData+4);
662b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if(!(
663b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pInfo->dataFormat[0]==0x54 &&   /* dataFormat="Norm" */
664b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pInfo->dataFormat[1]==0x65 &&
665b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pInfo->dataFormat[2]==0x73 &&
666b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pInfo->dataFormat[3]==0x74 &&
667b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pInfo->formatVersion[0]==1
668b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    )) {
669b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        udata_printError(ds, "test_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as testdata\n",
670b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         pInfo->dataFormat[0], pInfo->dataFormat[1],
671b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         pInfo->dataFormat[2], pInfo->dataFormat[3],
672b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                         pInfo->formatVersion[0]);
673b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        *pErrorCode=U_UNSUPPORTED_ERROR;
674b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return 0;
675b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
676b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
677b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    inBytes=(const uint8_t *)inData+headerSize;
678b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    outBytes=(uint8_t *)outData+headerSize;
679b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
680b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t size16 = 2; // 16bit plus padding
681b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t sizeStr = 5; // 4 char inv-str plus null
682b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t size = size16 + sizeStr;
683b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
684b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if(length>=0) {
685b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if(length<size) {
686b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            udata_printError(ds, "test_swap(): too few bytes (%d after header, wanted %d) for all of testdata\n",
687b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                             length, size);
688b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
689b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            return 0;
690b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
691b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
692b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru	offset =0;
693b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru	/* swap a 1 entry array */
694b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ds->swapArray16(ds, inBytes+offset, size16, outBytes+offset, pErrorCode);
695b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru	offset+=size16;
696b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru	ds->swapInvChars(ds, inBytes+offset, sizeStr, outBytes+offset, pErrorCode);
697b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
698b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
699b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return headerSize+size;
700b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
70150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* swap any data (except a .dat package) ------------------------------------ */
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const struct {
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t dataFormat[4];
706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDataSwapFn *swapFn;
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} swapFns[]={
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x52, 0x65, 0x73, 0x42 }, ures_swap },          /* dataFormat="ResB" */
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x63, 0x6e, 0x76, 0x74 }, ucnv_swap },          /* dataFormat="cnvt" */
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_CONVERSION
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x43, 0x76, 0x41, 0x6c }, ucnv_swapAliases },   /* dataFormat="CvAl" */
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_IDNA
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x53, 0x50, 0x52, 0x50 }, usprep_swap },        /* dataFormat="SPRP" */
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* insert data formats here, descending by expected frequency of occurrence */
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x55, 0x50, 0x72, 0x6f }, uprops_swap },        /* dataFormat="UPro" */
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { UCASE_FMT_0, UCASE_FMT_1, UCASE_FMT_2, UCASE_FMT_3 },
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  ucase_swap },         /* dataFormat="cAsE" */
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { UBIDI_FMT_0, UBIDI_FMT_1, UBIDI_FMT_2, UBIDI_FMT_3 },
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  ubidi_swap },         /* dataFormat="BiDi" */
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_NORMALIZATION
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x4e, 0x6f, 0x72, 0x6d }, unorm_swap },         /* dataFormat="Norm" */
72950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { { 0x4e, 0x72, 0x6d, 0x32 }, unorm2_swap },        /* dataFormat="Nrm2" */
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x55, 0x43, 0x6f, 0x6c }, ucol_swap },          /* dataFormat="UCol" */
733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x49, 0x6e, 0x76, 0x43 }, ucol_swapInverseUCA },/* dataFormat="InvC" */
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_BREAK_ITERATION
736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x42, 0x72, 0x6b, 0x20 }, ubrk_swap },          /* dataFormat="Brk " */
73754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    { { 0x44, 0x69, 0x63, 0x74 }, udict_swap },         /* dataFormat="Dict" */
738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    { { 0x70, 0x6e, 0x61, 0x6d }, upname_swap },        /* dataFormat="pnam" */
740b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    { { 0x75, 0x6e, 0x61, 0x6d }, uchar_swapNames },    /* dataFormat="unam" */
74150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_NORMALIZATION
742b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    { { 0x43, 0x66, 0x75, 0x20 }, uspoof_swap },         /* dataFormat="Cfu " */
74350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
744b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    { { 0x54, 0x65, 0x73, 0x74 }, test_swap }            /* dataFormat="Test" */
745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruudata_swap(const UDataSwapper *ds,
749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           const void *inData, int32_t length, void *outData,
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           UErrorCode *pErrorCode) {
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char dataFormatChars[4];
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UDataInfo *pInfo;
753103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t i, swappedLength;
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Preflight the header first; checks for illegal arguments, too.
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Do not swap the header right away because the format-specific swapper
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * will swap it, get the headerSize again, and also use the header
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * information. Otherwise we would have to pass some of the information
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * and not be able to use the UDataSwapFn signature.
765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    udata_swapDataHeader(ds, inData, -1, NULL, pErrorCode);
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * If we wanted udata_swap() to also handle non-loadable data like a UTrie,
770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * then we could check here for further known magic values and structures.
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0; /* the data format was not recognized */
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pInfo=(const UDataInfo *)((const char *)inData+4);
777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* convert the data format from ASCII to Unicode to the system charset */
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar u[4]={
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             pInfo->dataFormat[0], pInfo->dataFormat[1],
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             pInfo->dataFormat[2], pInfo->dataFormat[3]
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        };
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(uprv_isInvariantUString(u, 4)) {
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            u_UCharsToChars(u, dataFormatChars, 4);
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            dataFormatChars[0]=dataFormatChars[1]=dataFormatChars[2]=dataFormatChars[3]='?';
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* dispatch to the swap function for the dataFormat */
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(i=0; i<LENGTHOF(swapFns); ++i) {
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(0==memcmp(swapFns[i].dataFormat, pInfo->dataFormat, 4)) {
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            swappedLength=swapFns[i].swapFn(ds, inData, length, outData, pErrorCode);
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(U_FAILURE(*pErrorCode)) {
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                udata_printError(ds, "udata_swap(): failure swapping data format %02x.%02x.%02x.%02x (\"%c%c%c%c\") - %s\n",
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 pInfo->dataFormat[0], pInfo->dataFormat[1],
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 pInfo->dataFormat[2], pInfo->dataFormat[3],
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 dataFormatChars[0], dataFormatChars[1],
802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 dataFormatChars[2], dataFormatChars[3],
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 u_errorName(*pErrorCode));
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if(swappedLength<(length-15)) {
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* swapped less than expected */
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                udata_printError(ds, "udata_swap() warning: swapped only %d out of %d bytes - data format %02x.%02x.%02x.%02x (\"%c%c%c%c\")\n",
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 swappedLength, length,
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 pInfo->dataFormat[0], pInfo->dataFormat[1],
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 pInfo->dataFormat[2], pInfo->dataFormat[3],
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 dataFormatChars[0], dataFormatChars[1],
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 dataFormatChars[2], dataFormatChars[3],
812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 u_errorName(*pErrorCode));
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return swappedLength;
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* the dataFormat was not recognized */
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_printError(ds, "udata_swap(): unknown data format %02x.%02x.%02x.%02x (\"%c%c%c%c\")\n",
821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     pInfo->dataFormat[0], pInfo->dataFormat[1],
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     pInfo->dataFormat[2], pInfo->dataFormat[3],
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     dataFormatChars[0], dataFormatChars[1],
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     dataFormatChars[2], dataFormatChars[3]);
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *pErrorCode=U_UNSUPPORTED_ERROR;
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return 0;
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
829