OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * | 3 * |
4 * Copyright (C) 2003-2012, International Business Machines | 4 * Copyright (C) 2003-2014, International Business Machines |
5 * Corporation and others. All Rights Reserved. | 5 * Corporation and others. All Rights Reserved. |
6 * | 6 * |
7 ******************************************************************************* | 7 ******************************************************************************* |
8 * file name: ucol_swp.cpp | 8 * file name: ucol_swp.cpp |
9 * encoding: US-ASCII | 9 * encoding: US-ASCII |
10 * tab size: 8 (not used) | 10 * tab size: 8 (not used) |
11 * indentation:4 | 11 * indentation:4 |
12 * | 12 * |
13 * created on: 2003sep10 | 13 * created on: 2003sep10 |
14 * created by: Markus W. Scherer | 14 * created by: Markus W. Scherer |
15 * | 15 * |
16 * Swap collation binaries. | 16 * Swap collation binaries. |
17 */ | 17 */ |
18 | 18 |
19 #include "unicode/udata.h" /* UDataInfo */ | 19 #include "unicode/udata.h" /* UDataInfo */ |
20 #include "utrie.h" | 20 #include "utrie.h" |
| 21 #include "utrie2.h" |
21 #include "udataswp.h" | 22 #include "udataswp.h" |
22 #include "cmemory.h" | 23 #include "cmemory.h" |
23 #include "ucol_data.h" | 24 #include "ucol_data.h" |
24 #include "ucol_swp.h" | 25 #include "ucol_swp.h" |
25 | 26 |
26 /* swapping ----------------------------------------------------------------- */ | 27 /* swapping ----------------------------------------------------------------- */ |
27 | 28 |
28 /* | 29 /* |
29 * This performs data swapping for a folded trie (see utrie.c for details). | 30 * This performs data swapping for a folded trie (see utrie.c for details). |
30 */ | 31 */ |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 } else { | 96 } else { |
96 ds->swapArray16(ds, inTrie+1, (trie.indexLength+trie.dataLength)*2,
outTrie+1, pErrorCode); | 97 ds->swapArray16(ds, inTrie+1, (trie.indexLength+trie.dataLength)*2,
outTrie+1, pErrorCode); |
97 } | 98 } |
98 } | 99 } |
99 | 100 |
100 return size; | 101 return size; |
101 } | 102 } |
102 | 103 |
103 #if !UCONFIG_NO_COLLATION | 104 #if !UCONFIG_NO_COLLATION |
104 | 105 |
105 /* Modified copy of the beginning of ucol_swapBinary(). */ | |
106 U_CAPI UBool U_EXPORT2 | 106 U_CAPI UBool U_EXPORT2 |
107 ucol_looksLikeCollationBinary(const UDataSwapper *ds, | 107 ucol_looksLikeCollationBinary(const UDataSwapper *ds, |
108 const void *inData, int32_t length) { | 108 const void *inData, int32_t length) { |
109 const UCATableHeader *inHeader; | |
110 UCATableHeader header; | |
111 | |
112 if(ds==NULL || inData==NULL || length<-1) { | 109 if(ds==NULL || inData==NULL || length<-1) { |
113 return FALSE; | 110 return FALSE; |
114 } | 111 } |
115 | 112 |
116 inHeader=(const UCATableHeader *)inData; | 113 // First check for format version 4+ which has a standard data header. |
| 114 UErrorCode errorCode=U_ZERO_ERROR; |
| 115 (void)udata_swapDataHeader(ds, inData, -1, NULL, &errorCode); |
| 116 if(U_SUCCESS(errorCode)) { |
| 117 const UDataInfo &info=*(const UDataInfo *)((const char *)inData+4); |
| 118 if(info.dataFormat[0]==0x55 && // dataFormat="UCol" |
| 119 info.dataFormat[1]==0x43 && |
| 120 info.dataFormat[2]==0x6f && |
| 121 info.dataFormat[3]==0x6c) { |
| 122 return TRUE; |
| 123 } |
| 124 } |
| 125 |
| 126 // Else check for format version 3. |
| 127 const UCATableHeader *inHeader=(const UCATableHeader *)inData; |
117 | 128 |
118 /* | 129 /* |
119 * The collation binary must contain at least the UCATableHeader, | 130 * The collation binary must contain at least the UCATableHeader, |
120 * starting with its size field. | 131 * starting with its size field. |
121 * sizeof(UCATableHeader)==42*4 in ICU 2.8 | 132 * sizeof(UCATableHeader)==42*4 in ICU 2.8 |
122 * check the length against the header size before reading the size field | 133 * check the length against the header size before reading the size field |
123 */ | 134 */ |
| 135 UCATableHeader header; |
124 uprv_memset(&header, 0, sizeof(header)); | 136 uprv_memset(&header, 0, sizeof(header)); |
125 if(length<0) { | 137 if(length<0) { |
126 header.size=udata_readInt32(ds, inHeader->size); | 138 header.size=udata_readInt32(ds, inHeader->size); |
127 } else if((length<(42*4) || length<(header.size=udata_readInt32(ds, inHeader
->size)))) { | 139 } else if((length<(42*4) || length<(header.size=udata_readInt32(ds, inHeader
->size)))) { |
128 return FALSE; | 140 return FALSE; |
129 } | 141 } |
130 | 142 |
131 header.magic=ds->readUInt32(inHeader->magic); | 143 header.magic=ds->readUInt32(inHeader->magic); |
132 if(!( | 144 if(!( |
133 header.magic==UCOL_HEADER_MAGIC && | 145 header.magic==UCOL_HEADER_MAGIC && |
134 inHeader->formatVersion[0]==3 /*&& | 146 inHeader->formatVersion[0]==3 /*&& |
135 inHeader->formatVersion[1]>=0*/ | 147 inHeader->formatVersion[1]>=0*/ |
136 )) { | 148 )) { |
137 return FALSE; | 149 return FALSE; |
138 } | 150 } |
139 | 151 |
140 if(inHeader->isBigEndian!=ds->inIsBigEndian || inHeader->charSetFamily!=ds->
inCharset) { | 152 if(inHeader->isBigEndian!=ds->inIsBigEndian || inHeader->charSetFamily!=ds->
inCharset) { |
141 return FALSE; | 153 return FALSE; |
142 } | 154 } |
143 | 155 |
144 return TRUE; | 156 return TRUE; |
145 } | 157 } |
146 | 158 |
147 /* swap a header-less collation binary, inside a resource bundle or ucadata.icu
*/ | 159 namespace { |
148 U_CAPI int32_t U_EXPORT2 | 160 |
149 ucol_swapBinary(const UDataSwapper *ds, | 161 /* swap a header-less collation formatVersion=3 binary, inside a resource bundle
or ucadata.icu */ |
150 const void *inData, int32_t length, void *outData, | 162 int32_t |
151 UErrorCode *pErrorCode) { | 163 swapFormatVersion3(const UDataSwapper *ds, |
| 164 const void *inData, int32_t length, void *outData, |
| 165 UErrorCode *pErrorCode) { |
152 const uint8_t *inBytes; | 166 const uint8_t *inBytes; |
153 uint8_t *outBytes; | 167 uint8_t *outBytes; |
154 | 168 |
155 const UCATableHeader *inHeader; | 169 const UCATableHeader *inHeader; |
156 UCATableHeader *outHeader; | 170 UCATableHeader *outHeader; |
157 UCATableHeader header; | 171 UCATableHeader header; |
158 | 172 |
159 uint32_t count; | 173 uint32_t count; |
160 | 174 |
161 /* argument checking in case we were not called from ucol_swap() */ | 175 /* argument checking in case we were not called from ucol_swap() */ |
162 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { | 176 if(U_FAILURE(*pErrorCode)) { |
163 return 0; | 177 return 0; |
164 } | 178 } |
165 if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) { | 179 if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) { |
166 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; | 180 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
167 return 0; | 181 return 0; |
168 } | 182 } |
169 | 183 |
170 inBytes=(const uint8_t *)inData; | 184 inBytes=(const uint8_t *)inData; |
171 outBytes=(uint8_t *)outData; | 185 outBytes=(uint8_t *)outData; |
172 | 186 |
173 inHeader=(const UCATableHeader *)inData; | 187 inHeader=(const UCATableHeader *)inData; |
174 outHeader=(UCATableHeader *)outData; | 188 outHeader=(UCATableHeader *)outData; |
175 | 189 |
176 /* | 190 /* |
177 * The collation binary must contain at least the UCATableHeader, | 191 * The collation binary must contain at least the UCATableHeader, |
178 * starting with its size field. | 192 * starting with its size field. |
179 * sizeof(UCATableHeader)==42*4 in ICU 2.8 | 193 * sizeof(UCATableHeader)==42*4 in ICU 2.8 |
180 * check the length against the header size before reading the size field | 194 * check the length against the header size before reading the size field |
181 */ | 195 */ |
182 uprv_memset(&header, 0, sizeof(header)); | 196 uprv_memset(&header, 0, sizeof(header)); |
183 if(length<0) { | 197 if(length<0) { |
184 header.size=udata_readInt32(ds, inHeader->size); | 198 header.size=udata_readInt32(ds, inHeader->size); |
185 } else if((length<(42*4) || length<(header.size=udata_readInt32(ds, inHeader
->size)))) { | 199 } else if((length<(42*4) || length<(header.size=udata_readInt32(ds, inHeader
->size)))) { |
186 udata_printError(ds, "ucol_swapBinary(): too few bytes (%d after header)
for collation data\n", | 200 udata_printError(ds, "ucol_swap(formatVersion=3): too few bytes (%d afte
r header) for collation data\n", |
187 length); | 201 length); |
188 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; | 202 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
189 return 0; | 203 return 0; |
190 } | 204 } |
191 | 205 |
192 header.magic=ds->readUInt32(inHeader->magic); | 206 header.magic=ds->readUInt32(inHeader->magic); |
193 if(!( | 207 if(!( |
194 header.magic==UCOL_HEADER_MAGIC && | 208 header.magic==UCOL_HEADER_MAGIC && |
195 inHeader->formatVersion[0]==3 /*&& | 209 inHeader->formatVersion[0]==3 /*&& |
196 inHeader->formatVersion[1]>=0*/ | 210 inHeader->formatVersion[1]>=0*/ |
197 )) { | 211 )) { |
198 udata_printError(ds, "ucol_swapBinary(): magic 0x%08x or format version
%02x.%02x is not a collation binary\n", | 212 udata_printError(ds, "ucol_swap(formatVersion=3): magic 0x%08x or format
version %02x.%02x is not a collation binary\n", |
199 header.magic, | 213 header.magic, |
200 inHeader->formatVersion[0], inHeader->formatVersion[1])
; | 214 inHeader->formatVersion[0], inHeader->formatVersion[1])
; |
201 *pErrorCode=U_UNSUPPORTED_ERROR; | 215 *pErrorCode=U_UNSUPPORTED_ERROR; |
202 return 0; | 216 return 0; |
203 } | 217 } |
204 | 218 |
205 if(inHeader->isBigEndian!=ds->inIsBigEndian || inHeader->charSetFamily!=ds->
inCharset) { | 219 if(inHeader->isBigEndian!=ds->inIsBigEndian || inHeader->charSetFamily!=ds->
inCharset) { |
206 udata_printError(ds, "ucol_swapBinary(): endianness %d or charset %d doe
s not match the swapper\n", | 220 udata_printError(ds, "ucol_swap(formatVersion=3): endianness %d or chars
et %d does not match the swapper\n", |
207 inHeader->isBigEndian, inHeader->charSetFamily); | 221 inHeader->isBigEndian, inHeader->charSetFamily); |
208 *pErrorCode=U_INVALID_FORMAT_ERROR; | 222 *pErrorCode=U_INVALID_FORMAT_ERROR; |
209 return 0; | 223 return 0; |
210 } | 224 } |
211 | 225 |
212 if(length>=0) { | 226 if(length>=0) { |
213 /* copy everything, takes care of data that needs no swapping */ | 227 /* copy everything, takes care of data that needs no swapping */ |
214 if(inBytes!=outBytes) { | 228 if(inBytes!=outBytes) { |
215 uprv_memcpy(outBytes, inBytes, header.size); | 229 uprv_memcpy(outBytes, inBytes, header.size); |
216 } | 230 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 300 } |
287 | 301 |
288 /* expansionCESize, unsafeCP, contrEndCP: uint8_t[], no need to swap */ | 302 /* expansionCESize, unsafeCP, contrEndCP: uint8_t[], no need to swap */ |
289 | 303 |
290 /* swap UCA constants */ | 304 /* swap UCA constants */ |
291 if(header.UCAConsts!=0) { | 305 if(header.UCAConsts!=0) { |
292 /* | 306 /* |
293 * if UCAConsts!=0 then contractionUCACombos because we are swapping | 307 * if UCAConsts!=0 then contractionUCACombos because we are swapping |
294 * the UCA data file, and we know that the UCA contains contractions | 308 * the UCA data file, and we know that the UCA contains contractions |
295 */ | 309 */ |
296 count=header.contractionUCACombos-header.UCAConsts; | |
297 ds->swapArray32(ds, inBytes+header.UCAConsts, header.contractionUCAC
ombos-header.UCAConsts, | 310 ds->swapArray32(ds, inBytes+header.UCAConsts, header.contractionUCAC
ombos-header.UCAConsts, |
298 outBytes+header.UCAConsts, pErrorCode); | 311 outBytes+header.UCAConsts, pErrorCode); |
299 } | 312 } |
300 | 313 |
301 /* swap UCA contractions */ | 314 /* swap UCA contractions */ |
302 if(header.contractionUCACombosSize!=0) { | 315 if(header.contractionUCACombosSize!=0) { |
303 count=header.contractionUCACombosSize*inHeader->contractionUCACombos
Width*U_SIZEOF_UCHAR; | 316 count=header.contractionUCACombosSize*inHeader->contractionUCACombos
Width*U_SIZEOF_UCHAR; |
304 ds->swapArray16(ds, inBytes+header.contractionUCACombos, (int32_t)co
unt, | 317 ds->swapArray16(ds, inBytes+header.contractionUCACombos, (int32_t)co
unt, |
305 outBytes+header.contractionUCACombos, pErrorCode)
; | 318 outBytes+header.contractionUCACombos, pErrorCode)
; |
306 } | 319 } |
(...skipping 13 matching lines...) Expand all Loading... |
320 int dataCount = ds->readUInt16(*((uint16_t*)(inBytes+header.leadByte
ToScript + 2))); // each entry = uint16 | 333 int dataCount = ds->readUInt16(*((uint16_t*)(inBytes+header.leadByte
ToScript + 2))); // each entry = uint16 |
321 ds->swapArray16(ds, inBytes+header.leadByteToScript, | 334 ds->swapArray16(ds, inBytes+header.leadByteToScript, |
322 4 + (2 * indexCount) + (2 * dataCount), | 335 4 + (2 * indexCount) + (2 * dataCount), |
323 outBytes+header.leadByteToScript, pErrorCode); | 336 outBytes+header.leadByteToScript, pErrorCode); |
324 } | 337 } |
325 } | 338 } |
326 | 339 |
327 return header.size; | 340 return header.size; |
328 } | 341 } |
329 | 342 |
| 343 // swap formatVersion 4 ---------------------------------------------------- *** |
| 344 |
| 345 // The following are copied from CollationDataReader, trading an awkward copy of
constants |
| 346 // for an awkward relocation of the i18n collationdatareader.h file into the com
mon library. |
| 347 // Keep them in sync! |
| 348 |
| 349 enum { |
| 350 IX_INDEXES_LENGTH, // 0 |
| 351 IX_OPTIONS, |
| 352 IX_RESERVED2, |
| 353 IX_RESERVED3, |
| 354 |
| 355 IX_JAMO_CE32S_START, // 4 |
| 356 IX_REORDER_CODES_OFFSET, |
| 357 IX_REORDER_TABLE_OFFSET, |
| 358 IX_TRIE_OFFSET, |
| 359 |
| 360 IX_RESERVED8_OFFSET, // 8 |
| 361 IX_CES_OFFSET, |
| 362 IX_RESERVED10_OFFSET, |
| 363 IX_CE32S_OFFSET, |
| 364 |
| 365 IX_ROOT_ELEMENTS_OFFSET, // 12 |
| 366 IX_CONTEXTS_OFFSET, |
| 367 IX_UNSAFE_BWD_OFFSET, |
| 368 IX_FAST_LATIN_TABLE_OFFSET, |
| 369 |
| 370 IX_SCRIPTS_OFFSET, // 16 |
| 371 IX_COMPRESSIBLE_BYTES_OFFSET, |
| 372 IX_RESERVED18_OFFSET, |
| 373 IX_TOTAL_SIZE |
| 374 }; |
| 375 |
| 376 int32_t |
| 377 swapFormatVersion4(const UDataSwapper *ds, |
| 378 const void *inData, int32_t length, void *outData, |
| 379 UErrorCode &errorCode) { |
| 380 if(U_FAILURE(errorCode)) { return 0; } |
| 381 |
| 382 const uint8_t *inBytes=(const uint8_t *)inData; |
| 383 uint8_t *outBytes=(uint8_t *)outData; |
| 384 |
| 385 const int32_t *inIndexes=(const int32_t *)inBytes; |
| 386 int32_t indexes[IX_TOTAL_SIZE+1]; |
| 387 |
| 388 // Need at least IX_INDEXES_LENGTH and IX_OPTIONS. |
| 389 if(0<=length && length<8) { |
| 390 udata_printError(ds, "ucol_swap(formatVersion=4): too few bytes " |
| 391 "(%d after header) for collation data\n", |
| 392 length); |
| 393 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
| 394 return 0; |
| 395 } |
| 396 |
| 397 int32_t indexesLength=indexes[0]=udata_readInt32(ds, inIndexes[0]); |
| 398 if(0<=length && length<(indexesLength*4)) { |
| 399 udata_printError(ds, "ucol_swap(formatVersion=4): too few bytes " |
| 400 "(%d after header) for collation data\n", |
| 401 length); |
| 402 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
| 403 return 0; |
| 404 } |
| 405 |
| 406 for(int32_t i=1; i<=IX_TOTAL_SIZE && i<indexesLength; ++i) { |
| 407 indexes[i]=udata_readInt32(ds, inIndexes[i]); |
| 408 } |
| 409 for(int32_t i=indexesLength; i<=IX_TOTAL_SIZE; ++i) { |
| 410 indexes[i]=-1; |
| 411 } |
| 412 inIndexes=NULL; // Make sure we do not accidentally use these instead of in
dexes[]. |
| 413 |
| 414 // Get the total length of the data. |
| 415 int32_t size; |
| 416 if(indexesLength>IX_TOTAL_SIZE) { |
| 417 size=indexes[IX_TOTAL_SIZE]; |
| 418 } else if(indexesLength>IX_REORDER_CODES_OFFSET) { |
| 419 size=indexes[indexesLength-1]; |
| 420 } else { |
| 421 size=indexesLength*4; |
| 422 } |
| 423 if(length<0) { return size; } |
| 424 |
| 425 if(length<size) { |
| 426 udata_printError(ds, "ucol_swap(formatVersion=4): too few bytes " |
| 427 "(%d after header) for collation data\n", |
| 428 length); |
| 429 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
| 430 return 0; |
| 431 } |
| 432 |
| 433 // Copy the data for inaccessible bytes and arrays of bytes. |
| 434 if(inBytes!=outBytes) { |
| 435 uprv_memcpy(outBytes, inBytes, size); |
| 436 } |
| 437 |
| 438 // Swap the int32_t indexes[]. |
| 439 ds->swapArray32(ds, inBytes, indexesLength * 4, outBytes, &errorCode); |
| 440 |
| 441 // The following is a modified version of CollationDataReader::read(). |
| 442 // Here we use indexes[] not inIndexes[] because |
| 443 // the inIndexes[] may not be in this machine's endianness. |
| 444 int32_t index; // one of the indexes[] slots |
| 445 int32_t offset; // byte offset for the index part |
| 446 // int32_t length; // number of bytes in the index part |
| 447 |
| 448 index = IX_REORDER_CODES_OFFSET; |
| 449 offset = indexes[index]; |
| 450 length = indexes[index + 1] - offset; |
| 451 if(length > 0) { |
| 452 ds->swapArray32(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 453 } |
| 454 |
| 455 // Skip the IX_REORDER_TABLE_OFFSET byte array. |
| 456 |
| 457 index = IX_TRIE_OFFSET; |
| 458 offset = indexes[index]; |
| 459 length = indexes[index + 1] - offset; |
| 460 if(length > 0) { |
| 461 utrie2_swap(ds, inBytes + offset, length, outBytes + offset, &errorCode)
; |
| 462 } |
| 463 |
| 464 index = IX_RESERVED8_OFFSET; |
| 465 offset = indexes[index]; |
| 466 length = indexes[index + 1] - offset; |
| 467 if(length > 0) { |
| 468 udata_printError(ds, "ucol_swap(formatVersion=4): unknown data at IX_RES
ERVED8_OFFSET\n", length); |
| 469 errorCode = U_UNSUPPORTED_ERROR; |
| 470 return 0; |
| 471 } |
| 472 |
| 473 index = IX_CES_OFFSET; |
| 474 offset = indexes[index]; |
| 475 length = indexes[index + 1] - offset; |
| 476 if(length > 0) { |
| 477 ds->swapArray64(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 478 } |
| 479 |
| 480 index = IX_RESERVED10_OFFSET; |
| 481 offset = indexes[index]; |
| 482 length = indexes[index + 1] - offset; |
| 483 if(length > 0) { |
| 484 udata_printError(ds, "ucol_swap(formatVersion=4): unknown data at IX_RES
ERVED10_OFFSET\n", length); |
| 485 errorCode = U_UNSUPPORTED_ERROR; |
| 486 return 0; |
| 487 } |
| 488 |
| 489 index = IX_CE32S_OFFSET; |
| 490 offset = indexes[index]; |
| 491 length = indexes[index + 1] - offset; |
| 492 if(length > 0) { |
| 493 ds->swapArray32(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 494 } |
| 495 |
| 496 index = IX_ROOT_ELEMENTS_OFFSET; |
| 497 offset = indexes[index]; |
| 498 length = indexes[index + 1] - offset; |
| 499 if(length > 0) { |
| 500 ds->swapArray32(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 501 } |
| 502 |
| 503 index = IX_CONTEXTS_OFFSET; |
| 504 offset = indexes[index]; |
| 505 length = indexes[index + 1] - offset; |
| 506 if(length > 0) { |
| 507 ds->swapArray16(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 508 } |
| 509 |
| 510 index = IX_UNSAFE_BWD_OFFSET; |
| 511 offset = indexes[index]; |
| 512 length = indexes[index + 1] - offset; |
| 513 if(length > 0) { |
| 514 ds->swapArray16(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 515 } |
| 516 |
| 517 index = IX_FAST_LATIN_TABLE_OFFSET; |
| 518 offset = indexes[index]; |
| 519 length = indexes[index + 1] - offset; |
| 520 if(length > 0) { |
| 521 ds->swapArray16(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 522 } |
| 523 |
| 524 index = IX_SCRIPTS_OFFSET; |
| 525 offset = indexes[index]; |
| 526 length = indexes[index + 1] - offset; |
| 527 if(length > 0) { |
| 528 ds->swapArray16(ds, inBytes + offset, length, outBytes + offset, &errorC
ode); |
| 529 } |
| 530 |
| 531 // Skip the IX_COMPRESSIBLE_BYTES_OFFSET byte array. |
| 532 |
| 533 index = IX_RESERVED18_OFFSET; |
| 534 offset = indexes[index]; |
| 535 length = indexes[index + 1] - offset; |
| 536 if(length > 0) { |
| 537 udata_printError(ds, "ucol_swap(formatVersion=4): unknown data at IX_RES
ERVED18_OFFSET\n", length); |
| 538 errorCode = U_UNSUPPORTED_ERROR; |
| 539 return 0; |
| 540 } |
| 541 |
| 542 return size; |
| 543 } |
| 544 |
| 545 } // namespace |
| 546 |
330 /* swap ICU collation data like ucadata.icu */ | 547 /* swap ICU collation data like ucadata.icu */ |
331 U_CAPI int32_t U_EXPORT2 | 548 U_CAPI int32_t U_EXPORT2 |
332 ucol_swap(const UDataSwapper *ds, | 549 ucol_swap(const UDataSwapper *ds, |
333 const void *inData, int32_t length, void *outData, | 550 const void *inData, int32_t length, void *outData, |
334 UErrorCode *pErrorCode) { | 551 UErrorCode *pErrorCode) { |
335 | 552 if(U_FAILURE(*pErrorCode)) { return 0; } |
336 const UDataInfo *pInfo; | |
337 int32_t headerSize, collationSize; | |
338 | 553 |
339 /* udata_swapDataHeader checks the arguments */ | 554 /* udata_swapDataHeader checks the arguments */ |
340 headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); | 555 int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorC
ode); |
341 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { | 556 if(U_FAILURE(*pErrorCode)) { |
342 return 0; | 557 // Try to swap the old format version which did not have a standard data
header. |
| 558 *pErrorCode=U_ZERO_ERROR; |
| 559 return swapFormatVersion3(ds, inData, length, outData, pErrorCode); |
343 } | 560 } |
344 | 561 |
345 /* check data format and format version */ | 562 /* check data format and format version */ |
346 pInfo=(const UDataInfo *)((const char *)inData+4); | 563 const UDataInfo &info=*(const UDataInfo *)((const char *)inData+4); |
347 if(!( | 564 if(!( |
348 pInfo->dataFormat[0]==0x55 && /* dataFormat="UCol" */ | 565 info.dataFormat[0]==0x55 && // dataFormat="UCol" |
349 pInfo->dataFormat[1]==0x43 && | 566 info.dataFormat[1]==0x43 && |
350 pInfo->dataFormat[2]==0x6f && | 567 info.dataFormat[2]==0x6f && |
351 pInfo->dataFormat[3]==0x6c && | 568 info.dataFormat[3]==0x6c && |
352 pInfo->formatVersion[0]==3 /*&& | 569 (info.formatVersion[0]==3 || info.formatVersion[0]==4) |
353 pInfo->formatVersion[1]>=0*/ | |
354 )) { | 570 )) { |
355 udata_printError(ds, "ucol_swap(): data format %02x.%02x.%02x.%02x (form
at version %02x.%02x) is not a collation file\n", | 571 udata_printError(ds, "ucol_swap(): data format %02x.%02x.%02x.%02x " |
356 pInfo->dataFormat[0], pInfo->dataFormat[1], | 572 "(format version %02x.%02x) is not recognized as collat
ion data\n", |
357 pInfo->dataFormat[2], pInfo->dataFormat[3], | 573 info.dataFormat[0], info.dataFormat[1], |
358 pInfo->formatVersion[0], pInfo->formatVersion[1]); | 574 info.dataFormat[2], info.dataFormat[3], |
| 575 info.formatVersion[0], info.formatVersion[1]); |
359 *pErrorCode=U_UNSUPPORTED_ERROR; | 576 *pErrorCode=U_UNSUPPORTED_ERROR; |
360 return 0; | 577 return 0; |
361 } | 578 } |
362 | 579 |
363 collationSize=ucol_swapBinary(ds, | 580 inData=(const char *)inData+headerSize; |
364 (const char *)inData+headerSize, | 581 if(length>=0) { length-=headerSize; } |
365 length>=0 ? length-headerSize : -1, | 582 outData=(char *)outData+headerSize; |
366 (char *)outData+headerSize, | 583 int32_t collationSize; |
367 pErrorCode); | 584 if(info.formatVersion[0]>=4) { |
| 585 collationSize=swapFormatVersion4(ds, inData, length, outData, *pErrorCod
e); |
| 586 } else { |
| 587 collationSize=swapFormatVersion3(ds, inData, length, outData, pErrorCode
); |
| 588 } |
368 if(U_SUCCESS(*pErrorCode)) { | 589 if(U_SUCCESS(*pErrorCode)) { |
369 return headerSize+collationSize; | 590 return headerSize+collationSize; |
370 } else { | 591 } else { |
371 return 0; | 592 return 0; |
372 } | 593 } |
373 } | 594 } |
374 | 595 |
375 /* swap inverse UCA collation data (invuca.icu) */ | 596 /* swap inverse UCA collation data (invuca.icu) */ |
376 U_CAPI int32_t U_EXPORT2 | 597 U_CAPI int32_t U_EXPORT2 |
377 ucol_swapInverseUCA(const UDataSwapper *ds, | 598 ucol_swapInverseUCA(const UDataSwapper *ds, |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 679 |
459 /* swap the continuation table; contsSize counts UChars */ | 680 /* swap the continuation table; contsSize counts UChars */ |
460 ds->swapArray16(ds, inBytes+header.conts, header.contsSize*U_SIZEOF_UCHA
R, | 681 ds->swapArray16(ds, inBytes+header.conts, header.contsSize*U_SIZEOF_UCHA
R, |
461 outBytes+header.conts, pErrorCode); | 682 outBytes+header.conts, pErrorCode); |
462 } | 683 } |
463 | 684 |
464 return headerSize+header.byteSize; | 685 return headerSize+header.byteSize; |
465 } | 686 } |
466 | 687 |
467 #endif /* #if !UCONFIG_NO_COLLATION */ | 688 #endif /* #if !UCONFIG_NO_COLLATION */ |
OLD | NEW |