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