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