1/* 2********************************************************************** 3* Copyright (C) 2000-2007, International Business Machines 4* Corporation and others. All Rights Reserved. 5********************************************************************** 6* file name: ucnvlat1.cpp 7* encoding: US-ASCII 8* tab size: 8 (not used) 9* indentation:4 10* 11* created on: 2000feb07 12* created by: Markus W. Scherer 13*/ 14 15#include "unicode/utypes.h" 16 17#if !UCONFIG_NO_CONVERSION 18 19#include "unicode/ucnv.h" 20#include "unicode/uset.h" 21#include "ucnv_bld.h" 22#include "ucnv_cnv.h" 23 24/* control optimizations according to the platform */ 25#define LATIN1_UNROLL_FROM_UNICODE 1 26 27/* ISO 8859-1 --------------------------------------------------------------- */ 28 29/* This is a table-less and callback-less version of ucnv_MBCSSingleToBMPWithOffsets(). */ 30static void 31_Latin1ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, 32 UErrorCode *pErrorCode) { 33 const uint8_t *source; 34 UChar *target; 35 int32_t targetCapacity, length; 36 int32_t *offsets; 37 38 int32_t sourceIndex; 39 40 /* set up the local pointers */ 41 source=(const uint8_t *)pArgs->source; 42 target=pArgs->target; 43 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target); 44 offsets=pArgs->offsets; 45 46 sourceIndex=0; 47 48 /* 49 * since the conversion here is 1:1 UChar:uint8_t, we need only one counter 50 * for the minimum of the sourceLength and targetCapacity 51 */ 52 length=(int32_t)((const uint8_t *)pArgs->sourceLimit-source); 53 if(length<=targetCapacity) { 54 targetCapacity=length; 55 } else { 56 /* target will be full */ 57 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 58 length=targetCapacity; 59 } 60 61 if(targetCapacity>=8) { 62 /* This loop is unrolled for speed and improved pipelining. */ 63 int32_t count, loops; 64 65 loops=count=targetCapacity>>3; 66 length=targetCapacity&=0x7; 67 do { 68 target[0]=source[0]; 69 target[1]=source[1]; 70 target[2]=source[2]; 71 target[3]=source[3]; 72 target[4]=source[4]; 73 target[5]=source[5]; 74 target[6]=source[6]; 75 target[7]=source[7]; 76 target+=8; 77 source+=8; 78 } while(--count>0); 79 80 if(offsets!=NULL) { 81 do { 82 offsets[0]=sourceIndex++; 83 offsets[1]=sourceIndex++; 84 offsets[2]=sourceIndex++; 85 offsets[3]=sourceIndex++; 86 offsets[4]=sourceIndex++; 87 offsets[5]=sourceIndex++; 88 offsets[6]=sourceIndex++; 89 offsets[7]=sourceIndex++; 90 offsets+=8; 91 } while(--loops>0); 92 } 93 } 94 95 /* conversion loop */ 96 while(targetCapacity>0) { 97 *target++=*source++; 98 --targetCapacity; 99 } 100 101 /* write back the updated pointers */ 102 pArgs->source=(const char *)source; 103 pArgs->target=target; 104 105 /* set offsets */ 106 if(offsets!=NULL) { 107 while(length>0) { 108 *offsets++=sourceIndex++; 109 --length; 110 } 111 pArgs->offsets=offsets; 112 } 113} 114 115/* This is a table-less and callback-less version of ucnv_MBCSSingleGetNextUChar(). */ 116static UChar32 117_Latin1GetNextUChar(UConverterToUnicodeArgs *pArgs, 118 UErrorCode *pErrorCode) { 119 const uint8_t *source=(const uint8_t *)pArgs->source; 120 if(source<(const uint8_t *)pArgs->sourceLimit) { 121 pArgs->source=(const char *)(source+1); 122 return *source; 123 } 124 125 /* no output because of empty input */ 126 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 127 return 0xffff; 128} 129 130/* This is a table-less version of ucnv_MBCSSingleFromBMPWithOffsets(). */ 131static void 132_Latin1FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, 133 UErrorCode *pErrorCode) { 134 UConverter *cnv; 135 const UChar *source, *sourceLimit; 136 uint8_t *target, *oldTarget; 137 int32_t targetCapacity, length; 138 int32_t *offsets; 139 140 UChar32 cp; 141 UChar c, max; 142 143 int32_t sourceIndex; 144 145 /* set up the local pointers */ 146 cnv=pArgs->converter; 147 source=pArgs->source; 148 sourceLimit=pArgs->sourceLimit; 149 target=oldTarget=(uint8_t *)pArgs->target; 150 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target); 151 offsets=pArgs->offsets; 152 153 if(cnv->sharedData==&_Latin1Data) { 154 max=0xff; /* Latin-1 */ 155 } else { 156 max=0x7f; /* US-ASCII */ 157 } 158 159 /* get the converter state from UConverter */ 160 cp=cnv->fromUChar32; 161 162 /* sourceIndex=-1 if the current character began in the previous buffer */ 163 sourceIndex= cp==0 ? 0 : -1; 164 165 /* 166 * since the conversion here is 1:1 UChar:uint8_t, we need only one counter 167 * for the minimum of the sourceLength and targetCapacity 168 */ 169 length=(int32_t)(sourceLimit-source); 170 if(length<targetCapacity) { 171 targetCapacity=length; 172 } 173 174 /* conversion loop */ 175 if(cp!=0 && targetCapacity>0) { 176 goto getTrail; 177 } 178 179#if LATIN1_UNROLL_FROM_UNICODE 180 /* unroll the loop with the most common case */ 181 if(targetCapacity>=16) { 182 int32_t count, loops; 183 UChar u, oredChars; 184 185 loops=count=targetCapacity>>4; 186 do { 187 oredChars=u=*source++; 188 *target++=(uint8_t)u; 189 oredChars|=u=*source++; 190 *target++=(uint8_t)u; 191 oredChars|=u=*source++; 192 *target++=(uint8_t)u; 193 oredChars|=u=*source++; 194 *target++=(uint8_t)u; 195 oredChars|=u=*source++; 196 *target++=(uint8_t)u; 197 oredChars|=u=*source++; 198 *target++=(uint8_t)u; 199 oredChars|=u=*source++; 200 *target++=(uint8_t)u; 201 oredChars|=u=*source++; 202 *target++=(uint8_t)u; 203 oredChars|=u=*source++; 204 *target++=(uint8_t)u; 205 oredChars|=u=*source++; 206 *target++=(uint8_t)u; 207 oredChars|=u=*source++; 208 *target++=(uint8_t)u; 209 oredChars|=u=*source++; 210 *target++=(uint8_t)u; 211 oredChars|=u=*source++; 212 *target++=(uint8_t)u; 213 oredChars|=u=*source++; 214 *target++=(uint8_t)u; 215 oredChars|=u=*source++; 216 *target++=(uint8_t)u; 217 oredChars|=u=*source++; 218 *target++=(uint8_t)u; 219 220 /* were all 16 entries really valid? */ 221 if(oredChars>max) { 222 /* no, return to the first of these 16 */ 223 source-=16; 224 target-=16; 225 break; 226 } 227 } while(--count>0); 228 count=loops-count; 229 targetCapacity-=16*count; 230 231 if(offsets!=NULL) { 232 oldTarget+=16*count; 233 while(count>0) { 234 *offsets++=sourceIndex++; 235 *offsets++=sourceIndex++; 236 *offsets++=sourceIndex++; 237 *offsets++=sourceIndex++; 238 *offsets++=sourceIndex++; 239 *offsets++=sourceIndex++; 240 *offsets++=sourceIndex++; 241 *offsets++=sourceIndex++; 242 *offsets++=sourceIndex++; 243 *offsets++=sourceIndex++; 244 *offsets++=sourceIndex++; 245 *offsets++=sourceIndex++; 246 *offsets++=sourceIndex++; 247 *offsets++=sourceIndex++; 248 *offsets++=sourceIndex++; 249 *offsets++=sourceIndex++; 250 --count; 251 } 252 } 253 } 254#endif 255 256 /* conversion loop */ 257 c=0; 258 while(targetCapacity>0 && (c=*source++)<=max) { 259 /* convert the Unicode code point */ 260 *target++=(uint8_t)c; 261 --targetCapacity; 262 } 263 264 if(c>max) { 265 cp=c; 266 if(!U_IS_SURROGATE(cp)) { 267 /* callback(unassigned) */ 268 } else if(U_IS_SURROGATE_LEAD(cp)) { 269getTrail: 270 if(source<sourceLimit) { 271 /* test the following code unit */ 272 UChar trail=*source; 273 if(U16_IS_TRAIL(trail)) { 274 ++source; 275 cp=U16_GET_SUPPLEMENTARY(cp, trail); 276 /* this codepage does not map supplementary code points */ 277 /* callback(unassigned) */ 278 } else { 279 /* this is an unmatched lead code unit (1st surrogate) */ 280 /* callback(illegal) */ 281 } 282 } else { 283 /* no more input */ 284 cnv->fromUChar32=cp; 285 goto noMoreInput; 286 } 287 } else { 288 /* this is an unmatched trail code unit (2nd surrogate) */ 289 /* callback(illegal) */ 290 } 291 292 *pErrorCode= U_IS_SURROGATE(cp) ? U_ILLEGAL_CHAR_FOUND : U_INVALID_CHAR_FOUND; 293 cnv->fromUChar32=cp; 294 } 295noMoreInput: 296 297 /* set offsets since the start */ 298 if(offsets!=NULL) { 299 size_t count=target-oldTarget; 300 while(count>0) { 301 *offsets++=sourceIndex++; 302 --count; 303 } 304 } 305 306 if(U_SUCCESS(*pErrorCode) && source<sourceLimit && target>=(uint8_t *)pArgs->targetLimit) { 307 /* target is full */ 308 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 309 } 310 311 /* write back the updated pointers */ 312 pArgs->source=source; 313 pArgs->target=(char *)target; 314 pArgs->offsets=offsets; 315} 316 317/* Convert UTF-8 to Latin-1. Adapted from ucnv_SBCSFromUTF8(). */ 318static void 319ucnv_Latin1FromUTF8(UConverterFromUnicodeArgs *pFromUArgs, 320 UConverterToUnicodeArgs *pToUArgs, 321 UErrorCode *pErrorCode) { 322 UConverter *utf8; 323 const uint8_t *source, *sourceLimit; 324 uint8_t *target; 325 int32_t targetCapacity; 326 327 UChar32 c; 328 uint8_t b, t1; 329 330 /* set up the local pointers */ 331 utf8=pToUArgs->converter; 332 source=(uint8_t *)pToUArgs->source; 333 sourceLimit=(uint8_t *)pToUArgs->sourceLimit; 334 target=(uint8_t *)pFromUArgs->target; 335 targetCapacity=(int32_t)(pFromUArgs->targetLimit-pFromUArgs->target); 336 337 /* get the converter state from the UTF-8 UConverter */ 338 c=(UChar32)utf8->toUnicodeStatus; 339 if(c!=0 && source<sourceLimit) { 340 if(targetCapacity==0) { 341 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 342 return; 343 } else if(c>=0xc2 && c<=0xc3 && (t1=(uint8_t)(*source-0x80)) <= 0x3f) { 344 ++source; 345 *target++=(uint8_t)(((c&3)<<6)|t1); 346 --targetCapacity; 347 348 utf8->toUnicodeStatus=0; 349 utf8->toULength=0; 350 } else { 351 /* complicated, illegal or unmappable input: fall back to the pivoting implementation */ 352 *pErrorCode=U_USING_DEFAULT_WARNING; 353 return; 354 } 355 } 356 357 /* 358 * Make sure that the last byte sequence before sourceLimit is complete 359 * or runs into a lead byte. 360 * In the conversion loop compare source with sourceLimit only once 361 * per multi-byte character. 362 * For Latin-1, adjust sourceLimit only for 1 trail byte because 363 * the conversion loop handles at most 2-byte sequences. 364 */ 365 if(source<sourceLimit && U8_IS_LEAD(*(sourceLimit-1))) { 366 --sourceLimit; 367 } 368 369 /* conversion loop */ 370 while(source<sourceLimit) { 371 if(targetCapacity>0) { 372 b=*source++; 373 if((int8_t)b>=0) { 374 /* convert ASCII */ 375 *target++=(uint8_t)b; 376 --targetCapacity; 377 } else if( /* handle U+0080..U+00FF inline */ 378 b>=0xc2 && b<=0xc3 && 379 (t1=(uint8_t)(*source-0x80)) <= 0x3f 380 ) { 381 ++source; 382 *target++=(uint8_t)(((b&3)<<6)|t1); 383 --targetCapacity; 384 } else { 385 /* complicated, illegal or unmappable input: fall back to the pivoting implementation */ 386 pToUArgs->source=(char *)(source-1); 387 pFromUArgs->target=(char *)target; 388 *pErrorCode=U_USING_DEFAULT_WARNING; 389 return; 390 } 391 } else { 392 /* target is full */ 393 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 394 break; 395 } 396 } 397 398 /* 399 * The sourceLimit may have been adjusted before the conversion loop 400 * to stop before a truncated sequence. 401 * If so, then collect the truncated sequence now. 402 * For Latin-1, there is at most exactly one lead byte because of the 403 * smaller sourceLimit adjustment logic. 404 */ 405 if(U_SUCCESS(*pErrorCode) && source<(sourceLimit=(uint8_t *)pToUArgs->sourceLimit)) { 406 utf8->toUnicodeStatus=utf8->toUBytes[0]=b=*source++; 407 utf8->toULength=1; 408 utf8->mode=utf8_countTrailBytes[b]+1; 409 } 410 411 /* write back the updated pointers */ 412 pToUArgs->source=(char *)source; 413 pFromUArgs->target=(char *)target; 414} 415 416static void 417_Latin1GetUnicodeSet(const UConverter *cnv, 418 const USetAdder *sa, 419 UConverterUnicodeSet which, 420 UErrorCode *pErrorCode) { 421 sa->addRange(sa->set, 0, 0xff); 422} 423 424static const UConverterImpl _Latin1Impl={ 425 UCNV_LATIN_1, 426 427 NULL, 428 NULL, 429 430 NULL, 431 NULL, 432 NULL, 433 434 _Latin1ToUnicodeWithOffsets, 435 _Latin1ToUnicodeWithOffsets, 436 _Latin1FromUnicodeWithOffsets, 437 _Latin1FromUnicodeWithOffsets, 438 _Latin1GetNextUChar, 439 440 NULL, 441 NULL, 442 NULL, 443 NULL, 444 _Latin1GetUnicodeSet, 445 446 NULL, 447 ucnv_Latin1FromUTF8 448}; 449 450static const UConverterStaticData _Latin1StaticData={ 451 sizeof(UConverterStaticData), 452 "ISO-8859-1", 453 819, UCNV_IBM, UCNV_LATIN_1, 1, 1, 454 { 0x1a, 0, 0, 0 }, 1, FALSE, FALSE, 455 0, 456 0, 457 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */ 458}; 459 460const UConverterSharedData _Latin1Data={ 461 sizeof(UConverterSharedData), ~((uint32_t) 0), 462 NULL, NULL, &_Latin1StaticData, FALSE, &_Latin1Impl, 463 0 464}; 465 466/* US-ASCII ----------------------------------------------------------------- */ 467 468/* This is a table-less version of ucnv_MBCSSingleToBMPWithOffsets(). */ 469static void 470_ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, 471 UErrorCode *pErrorCode) { 472 const uint8_t *source, *sourceLimit; 473 UChar *target, *oldTarget; 474 int32_t targetCapacity, length; 475 int32_t *offsets; 476 477 int32_t sourceIndex; 478 479 uint8_t c; 480 481 /* set up the local pointers */ 482 source=(const uint8_t *)pArgs->source; 483 sourceLimit=(const uint8_t *)pArgs->sourceLimit; 484 target=oldTarget=pArgs->target; 485 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target); 486 offsets=pArgs->offsets; 487 488 /* sourceIndex=-1 if the current character began in the previous buffer */ 489 sourceIndex=0; 490 491 /* 492 * since the conversion here is 1:1 UChar:uint8_t, we need only one counter 493 * for the minimum of the sourceLength and targetCapacity 494 */ 495 length=(int32_t)(sourceLimit-source); 496 if(length<targetCapacity) { 497 targetCapacity=length; 498 } 499 500 if(targetCapacity>=8) { 501 /* This loop is unrolled for speed and improved pipelining. */ 502 int32_t count, loops; 503 UChar oredChars; 504 505 loops=count=targetCapacity>>3; 506 do { 507 oredChars=target[0]=source[0]; 508 oredChars|=target[1]=source[1]; 509 oredChars|=target[2]=source[2]; 510 oredChars|=target[3]=source[3]; 511 oredChars|=target[4]=source[4]; 512 oredChars|=target[5]=source[5]; 513 oredChars|=target[6]=source[6]; 514 oredChars|=target[7]=source[7]; 515 516 /* were all 16 entries really valid? */ 517 if(oredChars>0x7f) { 518 /* no, return to the first of these 16 */ 519 break; 520 } 521 source+=8; 522 target+=8; 523 } while(--count>0); 524 count=loops-count; 525 targetCapacity-=count*8; 526 527 if(offsets!=NULL) { 528 oldTarget+=count*8; 529 while(count>0) { 530 offsets[0]=sourceIndex++; 531 offsets[1]=sourceIndex++; 532 offsets[2]=sourceIndex++; 533 offsets[3]=sourceIndex++; 534 offsets[4]=sourceIndex++; 535 offsets[5]=sourceIndex++; 536 offsets[6]=sourceIndex++; 537 offsets[7]=sourceIndex++; 538 offsets+=8; 539 --count; 540 } 541 } 542 } 543 544 /* conversion loop */ 545 c=0; 546 while(targetCapacity>0 && (c=*source++)<=0x7f) { 547 *target++=c; 548 --targetCapacity; 549 } 550 551 if(c>0x7f) { 552 /* callback(illegal); copy the current bytes to toUBytes[] */ 553 UConverter *cnv=pArgs->converter; 554 cnv->toUBytes[0]=c; 555 cnv->toULength=1; 556 *pErrorCode=U_ILLEGAL_CHAR_FOUND; 557 } else if(source<sourceLimit && target>=pArgs->targetLimit) { 558 /* target is full */ 559 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 560 } 561 562 /* set offsets since the start */ 563 if(offsets!=NULL) { 564 size_t count=target-oldTarget; 565 while(count>0) { 566 *offsets++=sourceIndex++; 567 --count; 568 } 569 } 570 571 /* write back the updated pointers */ 572 pArgs->source=(const char *)source; 573 pArgs->target=target; 574 pArgs->offsets=offsets; 575} 576 577/* This is a table-less version of ucnv_MBCSSingleGetNextUChar(). */ 578static UChar32 579_ASCIIGetNextUChar(UConverterToUnicodeArgs *pArgs, 580 UErrorCode *pErrorCode) { 581 const uint8_t *source; 582 uint8_t b; 583 584 source=(const uint8_t *)pArgs->source; 585 if(source<(const uint8_t *)pArgs->sourceLimit) { 586 b=*source++; 587 pArgs->source=(const char *)source; 588 if(b<=0x7f) { 589 return b; 590 } else { 591 UConverter *cnv=pArgs->converter; 592 cnv->toUBytes[0]=b; 593 cnv->toULength=1; 594 *pErrorCode=U_ILLEGAL_CHAR_FOUND; 595 return 0xffff; 596 } 597 } 598 599 /* no output because of empty input */ 600 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 601 return 0xffff; 602} 603 604/* "Convert" UTF-8 to US-ASCII: Validate and copy. */ 605static void 606ucnv_ASCIIFromUTF8(UConverterFromUnicodeArgs *pFromUArgs, 607 UConverterToUnicodeArgs *pToUArgs, 608 UErrorCode *pErrorCode) { 609 const uint8_t *source, *sourceLimit; 610 uint8_t *target; 611 int32_t targetCapacity, length; 612 613 uint8_t c; 614 615 if(pToUArgs->converter->toUnicodeStatus!=0) { 616 /* no handling of partial UTF-8 characters here, fall back to pivoting */ 617 *pErrorCode=U_USING_DEFAULT_WARNING; 618 return; 619 } 620 621 /* set up the local pointers */ 622 source=(const uint8_t *)pToUArgs->source; 623 sourceLimit=(const uint8_t *)pToUArgs->sourceLimit; 624 target=(uint8_t *)pFromUArgs->target; 625 targetCapacity=(int32_t)(pFromUArgs->targetLimit-pFromUArgs->target); 626 627 /* 628 * since the conversion here is 1:1 uint8_t:uint8_t, we need only one counter 629 * for the minimum of the sourceLength and targetCapacity 630 */ 631 length=(int32_t)(sourceLimit-source); 632 if(length<targetCapacity) { 633 targetCapacity=length; 634 } 635 636 /* unroll the loop with the most common case */ 637 if(targetCapacity>=16) { 638 int32_t count, loops; 639 uint8_t oredChars; 640 641 loops=count=targetCapacity>>4; 642 do { 643 oredChars=*target++=*source++; 644 oredChars|=*target++=*source++; 645 oredChars|=*target++=*source++; 646 oredChars|=*target++=*source++; 647 oredChars|=*target++=*source++; 648 oredChars|=*target++=*source++; 649 oredChars|=*target++=*source++; 650 oredChars|=*target++=*source++; 651 oredChars|=*target++=*source++; 652 oredChars|=*target++=*source++; 653 oredChars|=*target++=*source++; 654 oredChars|=*target++=*source++; 655 oredChars|=*target++=*source++; 656 oredChars|=*target++=*source++; 657 oredChars|=*target++=*source++; 658 oredChars|=*target++=*source++; 659 660 /* were all 16 entries really valid? */ 661 if(oredChars>0x7f) { 662 /* no, return to the first of these 16 */ 663 source-=16; 664 target-=16; 665 break; 666 } 667 } while(--count>0); 668 count=loops-count; 669 targetCapacity-=16*count; 670 } 671 672 /* conversion loop */ 673 c=0; 674 while(targetCapacity>0 && (c=*source)<=0x7f) { 675 ++source; 676 *target++=c; 677 --targetCapacity; 678 } 679 680 if(c>0x7f) { 681 /* non-ASCII character, handle in standard converter */ 682 *pErrorCode=U_USING_DEFAULT_WARNING; 683 } else if(source<sourceLimit && target>=(const uint8_t *)pFromUArgs->targetLimit) { 684 /* target is full */ 685 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 686 } 687 688 /* write back the updated pointers */ 689 pToUArgs->source=(const char *)source; 690 pFromUArgs->target=(char *)target; 691} 692 693static void 694_ASCIIGetUnicodeSet(const UConverter *cnv, 695 const USetAdder *sa, 696 UConverterUnicodeSet which, 697 UErrorCode *pErrorCode) { 698 sa->addRange(sa->set, 0, 0x7f); 699} 700 701static const UConverterImpl _ASCIIImpl={ 702 UCNV_US_ASCII, 703 704 NULL, 705 NULL, 706 707 NULL, 708 NULL, 709 NULL, 710 711 _ASCIIToUnicodeWithOffsets, 712 _ASCIIToUnicodeWithOffsets, 713 _Latin1FromUnicodeWithOffsets, 714 _Latin1FromUnicodeWithOffsets, 715 _ASCIIGetNextUChar, 716 717 NULL, 718 NULL, 719 NULL, 720 NULL, 721 _ASCIIGetUnicodeSet, 722 723 NULL, 724 ucnv_ASCIIFromUTF8 725}; 726 727static const UConverterStaticData _ASCIIStaticData={ 728 sizeof(UConverterStaticData), 729 "US-ASCII", 730 367, UCNV_IBM, UCNV_US_ASCII, 1, 1, 731 { 0x1a, 0, 0, 0 }, 1, FALSE, FALSE, 732 0, 733 0, 734 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */ 735}; 736 737const UConverterSharedData _ASCIIData={ 738 sizeof(UConverterSharedData), ~((uint32_t) 0), 739 NULL, NULL, &_ASCIIStaticData, FALSE, &_ASCIIImpl, 740 0 741}; 742 743#endif 744