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