]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/ucnvlat1.c
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / common / ucnvlat1.c
CommitLineData
b75a7d8f
A
1/*
2**********************************************************************
46f4442e 3* Copyright (C) 2000-2007, International Business Machines
b75a7d8f
A
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"
374ca955
A
16
17#if !UCONFIG_NO_CONVERSION
18
b75a7d8f 19#include "unicode/ucnv.h"
b75a7d8f
A
20#include "unicode/uset.h"
21#include "ucnv_bld.h"
22#include "ucnv_cnv.h"
23
24/* control optimizations according to the platform */
b75a7d8f 25#define LATIN1_UNROLL_FROM_UNICODE 1
b75a7d8f
A
26
27/* ISO 8859-1 --------------------------------------------------------------- */
28
374ca955 29/* This is a table-less and callback-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
b75a7d8f
A
30static void
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;
73c04bcf 43 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target);
b75a7d8f
A
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 */
73c04bcf 52 length=(int32_t)((const uint8_t *)pArgs->sourceLimit-source);
b75a7d8f
A
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
46f4442e
A
61 if(targetCapacity>=8) {
62 /* This loop is unrolled for speed and improved pipelining. */
b75a7d8f
A
63 int32_t count, loops;
64
46f4442e
A
65 loops=count=targetCapacity>>3;
66 length=targetCapacity&=0x7;
b75a7d8f 67 do {
46f4442e
A
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;
b75a7d8f
A
78 } while(--count>0);
79
80 if(offsets!=NULL) {
81 do {
46f4442e
A
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;
b75a7d8f
A
91 } while(--loops>0);
92 }
93 }
b75a7d8f
A
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
374ca955 115/* This is a table-less and callback-less version of ucnv_MBCSSingleGetNextUChar(). */
b75a7d8f
A
116static UChar32
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
374ca955 130/* This is a table-less version of ucnv_MBCSSingleFromBMPWithOffsets(). */
b75a7d8f
A
131static void
132_Latin1FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
133 UErrorCode *pErrorCode) {
134 UConverter *cnv;
374ca955
A
135 const UChar *source, *sourceLimit;
136 uint8_t *target, *oldTarget;
b75a7d8f
A
137 int32_t targetCapacity, length;
138 int32_t *offsets;
139
374ca955
A
140 UChar32 cp;
141 UChar c, max;
b75a7d8f
A
142
143 int32_t sourceIndex;
144
b75a7d8f
A
145 /* set up the local pointers */
146 cnv=pArgs->converter;
147 source=pArgs->source;
148 sourceLimit=pArgs->sourceLimit;
374ca955 149 target=oldTarget=(uint8_t *)pArgs->target;
73c04bcf 150 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target);
b75a7d8f
A
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 */
374ca955 160 cp=cnv->fromUChar32;
b75a7d8f
A
161
162 /* sourceIndex=-1 if the current character began in the previous buffer */
374ca955 163 sourceIndex= cp==0 ? 0 : -1;
b75a7d8f
A
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 */
73c04bcf 169 length=(int32_t)(sourceLimit-source);
b75a7d8f
A
170 if(length<targetCapacity) {
171 targetCapacity=length;
172 }
173
174 /* conversion loop */
374ca955 175 if(cp!=0 && targetCapacity>0) {
b75a7d8f
A
176 goto getTrail;
177 }
178
179#if LATIN1_UNROLL_FROM_UNICODE
180 /* unroll the loop with the most common case */
b75a7d8f
A
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) {
374ca955 232 oldTarget+=16*count;
b75a7d8f
A
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 }
b75a7d8f
A
253 }
254#endif
255
374ca955
A
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)) {
b75a7d8f 269getTrail:
374ca955
A
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) */
b75a7d8f 278 } else {
374ca955
A
279 /* this is an unmatched lead code unit (1st surrogate) */
280 /* callback(illegal) */
b75a7d8f
A
281 }
282 } else {
374ca955
A
283 /* no more input */
284 cnv->fromUChar32=cp;
285 goto noMoreInput;
b75a7d8f 286 }
374ca955
A
287 } else {
288 /* this is an unmatched trail code unit (2nd surrogate) */
289 /* callback(illegal) */
b75a7d8f 290 }
b75a7d8f 291
374ca955
A
292 *pErrorCode= U_IS_SURROGATE(cp) ? U_ILLEGAL_CHAR_FOUND : U_INVALID_CHAR_FOUND;
293 cnv->fromUChar32=cp;
b75a7d8f 294 }
374ca955 295noMoreInput:
b75a7d8f 296
374ca955 297 /* set offsets since the start */
b75a7d8f 298 if(offsets!=NULL) {
374ca955 299 size_t count=target-oldTarget;
b75a7d8f
A
300 while(count>0) {
301 *offsets++=sourceIndex++;
302 --count;
303 }
304 }
305
374ca955
A
306 if(U_SUCCESS(*pErrorCode) && source<sourceLimit && target>=(uint8_t *)pArgs->targetLimit) {
307 /* target is full */
308 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
b75a7d8f
A
309 }
310
311 /* write back the updated pointers */
312 pArgs->source=source;
313 pArgs->target=(char *)target;
314 pArgs->offsets=offsets;
315}
316
46f4442e
A
317/* Convert UTF-8 to Latin-1. Adapted from ucnv_SBCSFromUTF8(). */
318static void
319ucnv_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
b75a7d8f
A
416static void
417_Latin1GetUnicodeSet(const UConverter *cnv,
73c04bcf 418 const USetAdder *sa,
b75a7d8f
A
419 UConverterUnicodeSet which,
420 UErrorCode *pErrorCode) {
374ca955 421 sa->addRange(sa->set, 0, 0xff);
b75a7d8f
A
422}
423
424static 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,
46f4442e
A
444 _Latin1GetUnicodeSet,
445
446 NULL,
447 ucnv_Latin1FromUTF8
b75a7d8f
A
448};
449
450static 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
460const UConverterSharedData _Latin1Data={
461 sizeof(UConverterSharedData), ~((uint32_t) 0),
462 NULL, NULL, &_Latin1StaticData, FALSE, &_Latin1Impl,
463 0
464};
465
466/* US-ASCII ----------------------------------------------------------------- */
467
374ca955 468/* This is a table-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
b75a7d8f
A
469static void
470_ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
471 UErrorCode *pErrorCode) {
374ca955
A
472 const uint8_t *source, *sourceLimit;
473 UChar *target, *oldTarget;
b75a7d8f
A
474 int32_t targetCapacity, length;
475 int32_t *offsets;
476
477 int32_t sourceIndex;
478
374ca955
A
479 uint8_t c;
480
b75a7d8f
A
481 /* set up the local pointers */
482 source=(const uint8_t *)pArgs->source;
483 sourceLimit=(const uint8_t *)pArgs->sourceLimit;
374ca955 484 target=oldTarget=pArgs->target;
73c04bcf 485 targetCapacity=(int32_t)(pArgs->targetLimit-pArgs->target);
b75a7d8f
A
486 offsets=pArgs->offsets;
487
488 /* sourceIndex=-1 if the current character began in the previous buffer */
489 sourceIndex=0;
b75a7d8f
A
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 */
73c04bcf 495 length=(int32_t)(sourceLimit-source);
b75a7d8f
A
496 if(length<targetCapacity) {
497 targetCapacity=length;
498 }
499
46f4442e
A
500 if(targetCapacity>=8) {
501 /* This loop is unrolled for speed and improved pipelining. */
b75a7d8f
A
502 int32_t count, loops;
503 UChar oredChars;
504
46f4442e 505 loops=count=targetCapacity>>3;
b75a7d8f 506 do {
46f4442e
A
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];
b75a7d8f
A
515
516 /* were all 16 entries really valid? */
517 if(oredChars>0x7f) {
518 /* no, return to the first of these 16 */
b75a7d8f
A
519 break;
520 }
46f4442e
A
521 source+=8;
522 target+=8;
b75a7d8f
A
523 } while(--count>0);
524 count=loops-count;
46f4442e 525 targetCapacity-=count*8;
b75a7d8f
A
526
527 if(offsets!=NULL) {
46f4442e 528 oldTarget+=count*8;
b75a7d8f 529 while(count>0) {
46f4442e
A
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;
b75a7d8f
A
539 --count;
540 }
541 }
542 }
b75a7d8f
A
543
544 /* conversion loop */
374ca955
A
545 c=0;
546 while(targetCapacity>0 && (c=*source++)<=0x7f) {
547 *target++=c;
548 --targetCapacity;
b75a7d8f
A
549 }
550
374ca955
A
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) {
b75a7d8f
A
558 /* target is full */
559 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
560 }
561
374ca955 562 /* set offsets since the start */
b75a7d8f 563 if(offsets!=NULL) {
374ca955 564 size_t count=target-oldTarget;
b75a7d8f
A
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
374ca955 577/* This is a table-less version of ucnv_MBCSSingleGetNextUChar(). */
b75a7d8f
A
578static UChar32
579_ASCIIGetNextUChar(UConverterToUnicodeArgs *pArgs,
580 UErrorCode *pErrorCode) {
b75a7d8f
A
581 const uint8_t *source;
582 uint8_t b;
583
b75a7d8f 584 source=(const uint8_t *)pArgs->source;
374ca955 585 if(source<(const uint8_t *)pArgs->sourceLimit) {
b75a7d8f
A
586 b=*source++;
587 pArgs->source=(const char *)source;
588 if(b<=0x7f) {
589 return b;
590 } else {
b75a7d8f 591 UConverter *cnv=pArgs->converter;
374ca955
A
592 cnv->toUBytes[0]=b;
593 cnv->toULength=1;
b75a7d8f 594 *pErrorCode=U_ILLEGAL_CHAR_FOUND;
374ca955 595 return 0xffff;
b75a7d8f
A
596 }
597 }
598
374ca955 599 /* no output because of empty input */
b75a7d8f
A
600 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
601 return 0xffff;
602}
603
46f4442e
A
604/* "Convert" UTF-8 to US-ASCII: Validate and copy. */
605static void
606ucnv_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
b75a7d8f
A
693static void
694_ASCIIGetUnicodeSet(const UConverter *cnv,
73c04bcf 695 const USetAdder *sa,
b75a7d8f
A
696 UConverterUnicodeSet which,
697 UErrorCode *pErrorCode) {
374ca955 698 sa->addRange(sa->set, 0, 0x7f);
b75a7d8f
A
699}
700
701static 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,
46f4442e
A
721 _ASCIIGetUnicodeSet,
722
723 NULL,
724 ucnv_ASCIIFromUTF8
b75a7d8f
A
725};
726
727static 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
737const UConverterSharedData _ASCIIData={
738 sizeof(UConverterSharedData), ~((uint32_t) 0),
739 NULL, NULL, &_ASCIIStaticData, FALSE, &_ASCIIImpl,
740 0
741};
374ca955
A
742
743#endif