Imported Upstream version 58.1
[platform/upstream/icu.git] / source / common / ucnvlat1.c
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
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
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
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
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
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
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
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
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
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