1 // Copyright (C) 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: US-ASCII
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
27 /* control optimizations according to the platform */
28 #define LATIN1_UNROLL_FROM_UNICODE 1
29
30 /* ISO 8859-1 --------------------------------------------------------------- */
31
32 /* This is a table-less and callback-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
33 static void
_Latin1ToUnicodeWithOffsets(UConverterToUnicodeArgs * pArgs,UErrorCode * pErrorCode)34 _Latin1ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
35 UErrorCode *pErrorCode) {
36 const uint8_t *source;
37 UChar *target;
38 int32_t targetCapacity, length;
39 int32_t *offsets;
40
41 int32_t sourceIndex;
42
43 /* set up the local pointers */
44 source=(const uint8_t *)pArgs->source;
45 target=pArgs->target;
46 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target);
47 offsets=pArgs->offsets;
48
49 sourceIndex=0;
50
51 /*
52 * since the conversion here is 1:1 UChar:uint8_t, we need only one counter
53 * for the minimum of the sourceLength and targetCapacity
54 */
55 length=(int32_t)((const uint8_t *)pArgs->sourceLimit-source);
56 if(length<=targetCapacity) {
57 targetCapacity=length;
58 } else {
59 /* target will be full */
60 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
61 length=targetCapacity;
62 }
63
64 if(targetCapacity>=8) {
65 /* This loop is unrolled for speed and improved pipelining. */
66 int32_t count, loops;
67
68 loops=count=targetCapacity>>3;
69 length=targetCapacity&=0x7;
70 do {
71 target[0]=source[0];
72 target[1]=source[1];
73 target[2]=source[2];
74 target[3]=source[3];
75 target[4]=source[4];
76 target[5]=source[5];
77 target[6]=source[6];
78 target[7]=source[7];
79 target+=8;
80 source+=8;
81 } while(--count>0);
82
83 if(offsets!=NULL) {
84 do {
85 offsets[0]=sourceIndex++;
86 offsets[1]=sourceIndex++;
87 offsets[2]=sourceIndex++;
88 offsets[3]=sourceIndex++;
89 offsets[4]=sourceIndex++;
90 offsets[5]=sourceIndex++;
91 offsets[6]=sourceIndex++;
92 offsets[7]=sourceIndex++;
93 offsets+=8;
94 } while(--loops>0);
95 }
96 }
97
98 /* conversion loop */
99 while(targetCapacity>0) {
100 *target++=*source++;
101 --targetCapacity;
102 }
103
104 /* write back the updated pointers */
105 pArgs->source=(const char *)source;
106 pArgs->target=target;
107
108 /* set offsets */
109 if(offsets!=NULL) {
110 while(length>0) {
111 *offsets++=sourceIndex++;
112 --length;
113 }
114 pArgs->offsets=offsets;
115 }
116 }
117
118 /* This is a table-less and callback-less version of ucnv_MBCSSingleGetNextUChar(). */
119 static UChar32
_Latin1GetNextUChar(UConverterToUnicodeArgs * pArgs,UErrorCode * pErrorCode)120 _Latin1GetNextUChar(UConverterToUnicodeArgs *pArgs,
121 UErrorCode *pErrorCode) {
122 const uint8_t *source=(const uint8_t *)pArgs->source;
123 if(source<(const uint8_t *)pArgs->sourceLimit) {
124 pArgs->source=(const char *)(source+1);
125 return *source;
126 }
127
128 /* no output because of empty input */
129 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
130 return 0xffff;
131 }
132
133 /* This is a table-less version of ucnv_MBCSSingleFromBMPWithOffsets(). */
134 static void
_Latin1FromUnicodeWithOffsets(UConverterFromUnicodeArgs * pArgs,UErrorCode * pErrorCode)135 _Latin1FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
136 UErrorCode *pErrorCode) {
137 UConverter *cnv;
138 const UChar *source, *sourceLimit;
139 uint8_t *target, *oldTarget;
140 int32_t targetCapacity, length;
141 int32_t *offsets;
142
143 UChar32 cp;
144 UChar c, max;
145
146 int32_t sourceIndex;
147
148 /* set up the local pointers */
149 cnv=pArgs->converter;
150 source=pArgs->source;
151 sourceLimit=pArgs->sourceLimit;
152 target=oldTarget=(uint8_t *)pArgs->target;
153 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target);
154 offsets=pArgs->offsets;
155
156 if(cnv->sharedData==&_Latin1Data) {
157 max=0xff; /* Latin-1 */
158 } else {
159 max=0x7f; /* US-ASCII */
160 }
161
162 /* get the converter state from UConverter */
163 cp=cnv->fromUChar32;
164
165 /* sourceIndex=-1 if the current character began in the previous buffer */
166 sourceIndex= cp==0 ? 0 : -1;
167
168 /*
169 * since the conversion here is 1:1 UChar:uint8_t, we need only one counter
170 * for the minimum of the sourceLength and targetCapacity
171 */
172 length=(int32_t)(sourceLimit-source);
173 if(length<targetCapacity) {
174 targetCapacity=length;
175 }
176
177 /* conversion loop */
178 if(cp!=0 && targetCapacity>0) {
179 goto getTrail;
180 }
181
182 #if LATIN1_UNROLL_FROM_UNICODE
183 /* unroll the loop with the most common case */
184 if(targetCapacity>=16) {
185 int32_t count, loops;
186 UChar u, oredChars;
187
188 loops=count=targetCapacity>>4;
189 do {
190 oredChars=u=*source++;
191 *target++=(uint8_t)u;
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
223 /* were all 16 entries really valid? */
224 if(oredChars>max) {
225 /* no, return to the first of these 16 */
226 source-=16;
227 target-=16;
228 break;
229 }
230 } while(--count>0);
231 count=loops-count;
232 targetCapacity-=16*count;
233
234 if(offsets!=NULL) {
235 oldTarget+=16*count;
236 while(count>0) {
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 *offsets++=sourceIndex++;
251 *offsets++=sourceIndex++;
252 *offsets++=sourceIndex++;
253 --count;
254 }
255 }
256 }
257 #endif
258
259 /* conversion loop */
260 c=0;
261 while(targetCapacity>0 && (c=*source++)<=max) {
262 /* convert the Unicode code point */
263 *target++=(uint8_t)c;
264 --targetCapacity;
265 }
266
267 if(c>max) {
268 cp=c;
269 if(!U_IS_SURROGATE(cp)) {
270 /* callback(unassigned) */
271 } else if(U_IS_SURROGATE_LEAD(cp)) {
272 getTrail:
273 if(source<sourceLimit) {
274 /* test the following code unit */
275 UChar trail=*source;
276 if(U16_IS_TRAIL(trail)) {
277 ++source;
278 cp=U16_GET_SUPPLEMENTARY(cp, trail);
279 /* this codepage does not map supplementary code points */
280 /* callback(unassigned) */
281 } else {
282 /* this is an unmatched lead code unit (1st surrogate) */
283 /* callback(illegal) */
284 }
285 } else {
286 /* no more input */
287 cnv->fromUChar32=cp;
288 goto noMoreInput;
289 }
290 } else {
291 /* this is an unmatched trail code unit (2nd surrogate) */
292 /* callback(illegal) */
293 }
294
295 *pErrorCode= U_IS_SURROGATE(cp) ? U_ILLEGAL_CHAR_FOUND : U_INVALID_CHAR_FOUND;
296 cnv->fromUChar32=cp;
297 }
298 noMoreInput:
299
300 /* set offsets since the start */
301 if(offsets!=NULL) {
302 size_t count=target-oldTarget;
303 while(count>0) {
304 *offsets++=sourceIndex++;
305 --count;
306 }
307 }
308
309 if(U_SUCCESS(*pErrorCode) && source<sourceLimit && target>=(uint8_t *)pArgs->targetLimit) {
310 /* target is full */
311 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
312 }
313
314 /* write back the updated pointers */
315 pArgs->source=source;
316 pArgs->target=(char *)target;
317 pArgs->offsets=offsets;
318 }
319
320 /* Convert UTF-8 to Latin-1. Adapted from ucnv_SBCSFromUTF8(). */
321 static void
ucnv_Latin1FromUTF8(UConverterFromUnicodeArgs * pFromUArgs,UConverterToUnicodeArgs * pToUArgs,UErrorCode * pErrorCode)322 ucnv_Latin1FromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
323 UConverterToUnicodeArgs *pToUArgs,
324 UErrorCode *pErrorCode) {
325 UConverter *utf8;
326 const uint8_t *source, *sourceLimit;
327 uint8_t *target;
328 int32_t targetCapacity;
329
330 UChar32 c;
331 uint8_t b, t1;
332
333 /* set up the local pointers */
334 utf8=pToUArgs->converter;
335 source=(uint8_t *)pToUArgs->source;
336 sourceLimit=(uint8_t *)pToUArgs->sourceLimit;
337 target=(uint8_t *)pFromUArgs->target;
338 targetCapacity=(int32_t)(pFromUArgs->targetLimit-pFromUArgs->target);
339
340 /* get the converter state from the UTF-8 UConverter */
341 c=(UChar32)utf8->toUnicodeStatus;
342 if(c!=0 && source<sourceLimit) {
343 if(targetCapacity==0) {
344 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
345 return;
346 } else if(c>=0xc2 && c<=0xc3 && (t1=(uint8_t)(*source-0x80)) <= 0x3f) {
347 ++source;
348 *target++=(uint8_t)(((c&3)<<6)|t1);
349 --targetCapacity;
350
351 utf8->toUnicodeStatus=0;
352 utf8->toULength=0;
353 } else {
354 /* complicated, illegal or unmappable input: fall back to the pivoting implementation */
355 *pErrorCode=U_USING_DEFAULT_WARNING;
356 return;
357 }
358 }
359
360 /*
361 * Make sure that the last byte sequence before sourceLimit is complete
362 * or runs into a lead byte.
363 * In the conversion loop compare source with sourceLimit only once
364 * per multi-byte character.
365 * For Latin-1, adjust sourceLimit only for 1 trail byte because
366 * the conversion loop handles at most 2-byte sequences.
367 */
368 if(source<sourceLimit && U8_IS_LEAD(*(sourceLimit-1))) {
369 --sourceLimit;
370 }
371
372 /* conversion loop */
373 while(source<sourceLimit) {
374 if(targetCapacity>0) {
375 b=*source++;
376 if((int8_t)b>=0) {
377 /* convert ASCII */
378 *target++=(uint8_t)b;
379 --targetCapacity;
380 } else if( /* handle U+0080..U+00FF inline */
381 b>=0xc2 && b<=0xc3 &&
382 (t1=(uint8_t)(*source-0x80)) <= 0x3f
383 ) {
384 ++source;
385 *target++=(uint8_t)(((b&3)<<6)|t1);
386 --targetCapacity;
387 } else {
388 /* complicated, illegal or unmappable input: fall back to the pivoting implementation */
389 pToUArgs->source=(char *)(source-1);
390 pFromUArgs->target=(char *)target;
391 *pErrorCode=U_USING_DEFAULT_WARNING;
392 return;
393 }
394 } else {
395 /* target is full */
396 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
397 break;
398 }
399 }
400
401 /*
402 * The sourceLimit may have been adjusted before the conversion loop
403 * to stop before a truncated sequence.
404 * If so, then collect the truncated sequence now.
405 * For Latin-1, there is at most exactly one lead byte because of the
406 * smaller sourceLimit adjustment logic.
407 */
408 if(U_SUCCESS(*pErrorCode) && source<(sourceLimit=(uint8_t *)pToUArgs->sourceLimit)) {
409 utf8->toUnicodeStatus=utf8->toUBytes[0]=b=*source++;
410 utf8->toULength=1;
411 utf8->mode=U8_COUNT_TRAIL_BYTES(b)+1;
412 }
413
414 /* write back the updated pointers */
415 pToUArgs->source=(char *)source;
416 pFromUArgs->target=(char *)target;
417 }
418
419 static void
_Latin1GetUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)420 _Latin1GetUnicodeSet(const UConverter *cnv,
421 const USetAdder *sa,
422 UConverterUnicodeSet which,
423 UErrorCode *pErrorCode) {
424 sa->addRange(sa->set, 0, 0xff);
425 }
426
427 static const UConverterImpl _Latin1Impl={
428 UCNV_LATIN_1,
429
430 NULL,
431 NULL,
432
433 NULL,
434 NULL,
435 NULL,
436
437 _Latin1ToUnicodeWithOffsets,
438 _Latin1ToUnicodeWithOffsets,
439 _Latin1FromUnicodeWithOffsets,
440 _Latin1FromUnicodeWithOffsets,
441 _Latin1GetNextUChar,
442
443 NULL,
444 NULL,
445 NULL,
446 NULL,
447 _Latin1GetUnicodeSet,
448
449 NULL,
450 ucnv_Latin1FromUTF8
451 };
452
453 static const UConverterStaticData _Latin1StaticData={
454 sizeof(UConverterStaticData),
455 "ISO-8859-1",
456 819, UCNV_IBM, UCNV_LATIN_1, 1, 1,
457 { 0x1a, 0, 0, 0 }, 1, FALSE, FALSE,
458 0,
459 0,
460 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
461 };
462
463 const UConverterSharedData _Latin1Data=
464 UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_Latin1StaticData, &_Latin1Impl);
465
466 /* US-ASCII ----------------------------------------------------------------- */
467
468 /* This is a table-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
469 static void
_ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs * pArgs,UErrorCode * pErrorCode)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(). */
578 static UChar32
_ASCIIGetNextUChar(UConverterToUnicodeArgs * pArgs,UErrorCode * pErrorCode)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. */
605 static void
ucnv_ASCIIFromUTF8(UConverterFromUnicodeArgs * pFromUArgs,UConverterToUnicodeArgs * pToUArgs,UErrorCode * pErrorCode)606 ucnv_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
693 static void
_ASCIIGetUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)694 _ASCIIGetUnicodeSet(const UConverter *cnv,
695 const USetAdder *sa,
696 UConverterUnicodeSet which,
697 UErrorCode *pErrorCode) {
698 sa->addRange(sa->set, 0, 0x7f);
699 }
700
701 static 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
727 static 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
737 const UConverterSharedData _ASCIIData=
738 UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_ASCIIStaticData, &_ASCIIImpl);
739
740 #endif
741