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