1 /*
2 **********************************************************************
3 *   Copyright (C) 2000-2012, 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     sizeof(UConverterSharedData), ~((uint32_t) 0),
463     NULL, NULL, &_Latin1StaticData, FALSE, &_Latin1Impl,
464     0
465 };
466 
467 /* US-ASCII ----------------------------------------------------------------- */
468 
469 /* This is a table-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
470 static void
_ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs * pArgs,UErrorCode * pErrorCode)471 _ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
472                            UErrorCode *pErrorCode) {
473     const uint8_t *source, *sourceLimit;
474     UChar *target, *oldTarget;
475     int32_t targetCapacity, length;
476     int32_t *offsets;
477 
478     int32_t sourceIndex;
479 
480     uint8_t c;
481 
482     /* set up the local pointers */
483     source=(const uint8_t *)pArgs->source;
484     sourceLimit=(const uint8_t *)pArgs->sourceLimit;
485     target=oldTarget=pArgs->target;
486     targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target);
487     offsets=pArgs->offsets;
488 
489     /* sourceIndex=-1 if the current character began in the previous buffer */
490     sourceIndex=0;
491 
492     /*
493      * since the conversion here is 1:1 UChar:uint8_t, we need only one counter
494      * for the minimum of the sourceLength and targetCapacity
495      */
496     length=(int32_t)(sourceLimit-source);
497     if(length<targetCapacity) {
498         targetCapacity=length;
499     }
500 
501     if(targetCapacity>=8) {
502         /* This loop is unrolled for speed and improved pipelining. */
503         int32_t count, loops;
504         UChar oredChars;
505 
506         loops=count=targetCapacity>>3;
507         do {
508             oredChars=target[0]=source[0];
509             oredChars|=target[1]=source[1];
510             oredChars|=target[2]=source[2];
511             oredChars|=target[3]=source[3];
512             oredChars|=target[4]=source[4];
513             oredChars|=target[5]=source[5];
514             oredChars|=target[6]=source[6];
515             oredChars|=target[7]=source[7];
516 
517             /* were all 16 entries really valid? */
518             if(oredChars>0x7f) {
519                 /* no, return to the first of these 16 */
520                 break;
521             }
522             source+=8;
523             target+=8;
524         } while(--count>0);
525         count=loops-count;
526         targetCapacity-=count*8;
527 
528         if(offsets!=NULL) {
529             oldTarget+=count*8;
530             while(count>0) {
531                 offsets[0]=sourceIndex++;
532                 offsets[1]=sourceIndex++;
533                 offsets[2]=sourceIndex++;
534                 offsets[3]=sourceIndex++;
535                 offsets[4]=sourceIndex++;
536                 offsets[5]=sourceIndex++;
537                 offsets[6]=sourceIndex++;
538                 offsets[7]=sourceIndex++;
539                 offsets+=8;
540                 --count;
541             }
542         }
543     }
544 
545     /* conversion loop */
546     c=0;
547     while(targetCapacity>0 && (c=*source++)<=0x7f) {
548         *target++=c;
549         --targetCapacity;
550     }
551 
552     if(c>0x7f) {
553         /* callback(illegal); copy the current bytes to toUBytes[] */
554         UConverter *cnv=pArgs->converter;
555         cnv->toUBytes[0]=c;
556         cnv->toULength=1;
557         *pErrorCode=U_ILLEGAL_CHAR_FOUND;
558     } else if(source<sourceLimit && target>=pArgs->targetLimit) {
559         /* target is full */
560         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
561     }
562 
563     /* set offsets since the start */
564     if(offsets!=NULL) {
565         size_t count=target-oldTarget;
566         while(count>0) {
567             *offsets++=sourceIndex++;
568             --count;
569         }
570     }
571 
572     /* write back the updated pointers */
573     pArgs->source=(const char *)source;
574     pArgs->target=target;
575     pArgs->offsets=offsets;
576 }
577 
578 /* This is a table-less version of ucnv_MBCSSingleGetNextUChar(). */
579 static UChar32
_ASCIIGetNextUChar(UConverterToUnicodeArgs * pArgs,UErrorCode * pErrorCode)580 _ASCIIGetNextUChar(UConverterToUnicodeArgs *pArgs,
581                    UErrorCode *pErrorCode) {
582     const uint8_t *source;
583     uint8_t b;
584 
585     source=(const uint8_t *)pArgs->source;
586     if(source<(const uint8_t *)pArgs->sourceLimit) {
587         b=*source++;
588         pArgs->source=(const char *)source;
589         if(b<=0x7f) {
590             return b;
591         } else {
592             UConverter *cnv=pArgs->converter;
593             cnv->toUBytes[0]=b;
594             cnv->toULength=1;
595             *pErrorCode=U_ILLEGAL_CHAR_FOUND;
596             return 0xffff;
597         }
598     }
599 
600     /* no output because of empty input */
601     *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
602     return 0xffff;
603 }
604 
605 /* "Convert" UTF-8 to US-ASCII: Validate and copy. */
606 static void
ucnv_ASCIIFromUTF8(UConverterFromUnicodeArgs * pFromUArgs,UConverterToUnicodeArgs * pToUArgs,UErrorCode * pErrorCode)607 ucnv_ASCIIFromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
608                    UConverterToUnicodeArgs *pToUArgs,
609                    UErrorCode *pErrorCode) {
610     const uint8_t *source, *sourceLimit;
611     uint8_t *target;
612     int32_t targetCapacity, length;
613 
614     uint8_t c;
615 
616     if(pToUArgs->converter->toUnicodeStatus!=0) {
617         /* no handling of partial UTF-8 characters here, fall back to pivoting */
618         *pErrorCode=U_USING_DEFAULT_WARNING;
619         return;
620     }
621 
622     /* set up the local pointers */
623     source=(const uint8_t *)pToUArgs->source;
624     sourceLimit=(const uint8_t *)pToUArgs->sourceLimit;
625     target=(uint8_t *)pFromUArgs->target;
626     targetCapacity=(int32_t)(pFromUArgs->targetLimit-pFromUArgs->target);
627 
628     /*
629      * since the conversion here is 1:1 uint8_t:uint8_t, we need only one counter
630      * for the minimum of the sourceLength and targetCapacity
631      */
632     length=(int32_t)(sourceLimit-source);
633     if(length<targetCapacity) {
634         targetCapacity=length;
635     }
636 
637     /* unroll the loop with the most common case */
638     if(targetCapacity>=16) {
639         int32_t count, loops;
640         uint8_t oredChars;
641 
642         loops=count=targetCapacity>>4;
643         do {
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             oredChars|=*target++=*source++;
660 
661             /* were all 16 entries really valid? */
662             if(oredChars>0x7f) {
663                 /* no, return to the first of these 16 */
664                 source-=16;
665                 target-=16;
666                 break;
667             }
668         } while(--count>0);
669         count=loops-count;
670         targetCapacity-=16*count;
671     }
672 
673     /* conversion loop */
674     c=0;
675     while(targetCapacity>0 && (c=*source)<=0x7f) {
676         ++source;
677         *target++=c;
678         --targetCapacity;
679     }
680 
681     if(c>0x7f) {
682         /* non-ASCII character, handle in standard converter */
683         *pErrorCode=U_USING_DEFAULT_WARNING;
684     } else if(source<sourceLimit && target>=(const uint8_t *)pFromUArgs->targetLimit) {
685         /* target is full */
686         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
687     }
688 
689     /* write back the updated pointers */
690     pToUArgs->source=(const char *)source;
691     pFromUArgs->target=(char *)target;
692 }
693 
694 static void
_ASCIIGetUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)695 _ASCIIGetUnicodeSet(const UConverter *cnv,
696                     const USetAdder *sa,
697                     UConverterUnicodeSet which,
698                     UErrorCode *pErrorCode) {
699     sa->addRange(sa->set, 0, 0x7f);
700 }
701 
702 static const UConverterImpl _ASCIIImpl={
703     UCNV_US_ASCII,
704 
705     NULL,
706     NULL,
707 
708     NULL,
709     NULL,
710     NULL,
711 
712     _ASCIIToUnicodeWithOffsets,
713     _ASCIIToUnicodeWithOffsets,
714     _Latin1FromUnicodeWithOffsets,
715     _Latin1FromUnicodeWithOffsets,
716     _ASCIIGetNextUChar,
717 
718     NULL,
719     NULL,
720     NULL,
721     NULL,
722     _ASCIIGetUnicodeSet,
723 
724     NULL,
725     ucnv_ASCIIFromUTF8
726 };
727 
728 static const UConverterStaticData _ASCIIStaticData={
729     sizeof(UConverterStaticData),
730     "US-ASCII",
731     367, UCNV_IBM, UCNV_US_ASCII, 1, 1,
732     { 0x1a, 0, 0, 0 }, 1, FALSE, FALSE,
733     0,
734     0,
735     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
736 };
737 
738 const UConverterSharedData _ASCIIData={
739     sizeof(UConverterSharedData), ~((uint32_t) 0),
740     NULL, NULL, &_ASCIIStaticData, FALSE, &_ASCIIImpl,
741     0
742 };
743 
744 #endif
745