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