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