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(). */
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;
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(). */
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
130/* This is a table-less version of ucnv_MBCSSingleFromBMPWithOffsets(). */
131static void
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)) {
269getTrail:
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    }
295noMoreInput:
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(). */
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
416static void
417_Latin1GetUnicodeSet(const UConverter *cnv,
418                     const USetAdder *sa,
419                     UConverterUnicodeSet which,
420                     UErrorCode *pErrorCode) {
421    sa->addRange(sa->set, 0, 0xff);
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,
444    _Latin1GetUnicodeSet,
445
446    NULL,
447    ucnv_Latin1FromUTF8
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
468/* This is a table-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
469static void
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(). */
578static UChar32
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. */
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
693static void
694_ASCIIGetUnicodeSet(const UConverter *cnv,
695                    const USetAdder *sa,
696                    UConverterUnicodeSet which,
697                    UErrorCode *pErrorCode) {
698    sa->addRange(sa->set, 0, 0x7f);
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,
721    _ASCIIGetUnicodeSet,
722
723    NULL,
724    ucnv_ASCIIFromUTF8
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};
742
743#endif
744