164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others.
264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
51b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert*   Copyright (C) 2002-2015, International Business Machines
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   file name:  ucnv_u32.c
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   encoding:   US-ASCII
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   tab size:   8 (not used)
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   indentation:4
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   created on: 2002jul01
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   created by: Markus W. Scherer
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   UTF-32 converter implementation. Used to be in ucnv_utf.c.
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#if !UCONFIG_NO_CONVERSION && !UCONFIG_ONLY_HTML_CONVERSION
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv.h"
2483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf.h"
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_bld.h"
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_cnv.h"
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAXIMUM_UCS2            0x0000FFFF
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAXIMUM_UTF             0x0010FFFF
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define HALF_SHIFT              10
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define HALF_BASE               0x0010000
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define HALF_MASK               0x3FF
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SURROGATE_HIGH_START    0xD800
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SURROGATE_LOW_START     0xDC00
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* -SURROGATE_LOW_START + HALF_BASE */
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SURROGATE_LOW_BASE      9216
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum {
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_NEED_TO_WRITE_BOM=1
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* UTF-32BE ----------------------------------------------------------------- */
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_toUnicode_UTF32_BE(UConverterToUnicodeArgs * args,
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                UErrorCode * err)
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *mySource = (unsigned char *) args->source;
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *myTarget = args->target;
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *targetLimit = args->targetLimit;
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *toUBytes = args->converter->toUBytes;
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t ch, i;
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Restore state of current sequence */
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->toUnicodeStatus && myTarget < targetLimit) {
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = args->converter->toULength;       /* restore # of bytes consumed */
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toULength = 0;
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->toUnicodeStatus - 1;/*Stores the previously calculated ch from a previous call*/
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toUnicodeStatus = 0;
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto morebytes;
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit) {
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = 0;
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = 0;
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querumorebytes:
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (i < sizeof(uint32_t)) {
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (mySource < sourceLimit) {
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch = (ch << 8) | (uint8_t)(*mySource);
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                toUBytes[i++] = (char) *(mySource++);
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* stores a partially calculated target*/
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* + 1 to make 0 a valid character */
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toUnicodeStatus = ch + 1;
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toULength = (int8_t) i;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto donefornow;
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch)) {
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ch <= MAXIMUM_UCS2)
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* fits in 16 bits */
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = (UChar) ch;
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* write out the surrogates */
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = U16_LEAD(ch);
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch = U16_TRAIL(ch);
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (myTarget < targetLimit) {
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *(myTarget++) = (UChar)ch;
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* Put in overflow buffer (not handled here) */
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBufferLength = 1;
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *err = U_BUFFER_OVERFLOW_ERROR;
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            args->converter->toULength = (int8_t)i;
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *err = U_ILLEGAL_CHAR_FOUND;
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudonefornow:
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err)) {
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* End of target buffer */
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = myTarget;
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = (const char *) mySource;
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC(UConverterToUnicodeArgs * args,
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                             UErrorCode * err)
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *mySource = (unsigned char *) args->source;
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *myTarget = args->target;
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t *myOffsets = args->offsets;
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *targetLimit = args->targetLimit;
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *toUBytes = args->converter->toUBytes;
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t ch, i;
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t offsetNum = 0;
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Restore state of current sequence */
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->toUnicodeStatus && myTarget < targetLimit) {
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = args->converter->toULength;       /* restore # of bytes consumed */
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toULength = 0;
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->toUnicodeStatus - 1;/*Stores the previously calculated ch from a previous call*/
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toUnicodeStatus = 0;
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto morebytes;
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit) {
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = 0;
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = 0;
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querumorebytes:
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (i < sizeof(uint32_t)) {
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (mySource < sourceLimit) {
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch = (ch << 8) | (uint8_t)(*mySource);
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                toUBytes[i++] = (char) *(mySource++);
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* stores a partially calculated target*/
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* + 1 to make 0 a valid character */
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toUnicodeStatus = ch + 1;
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toULength = (int8_t) i;
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto donefornow;
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch)) {
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ch <= MAXIMUM_UCS2) {
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* fits in 16 bits */
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = (UChar) ch;
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myOffsets++) = offsetNum;
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* write out the surrogates */
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = U16_LEAD(ch);
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *myOffsets++ = offsetNum;
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch = U16_TRAIL(ch);
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (myTarget < targetLimit)
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                {
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *(myTarget++) = (UChar)ch;
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *(myOffsets++) = offsetNum;
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* Put in overflow buffer (not handled here) */
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBufferLength = 1;
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *err = U_BUFFER_OVERFLOW_ERROR;
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            args->converter->toULength = (int8_t)i;
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *err = U_ILLEGAL_CHAR_FOUND;
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offsetNum += i;
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudonefornow:
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* End of target buffer */
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = myTarget;
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = (const char *) mySource;
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->offsets = myOffsets;
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_fromUnicode_UTF32_BE(UConverterFromUnicodeArgs * args,
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                  UErrorCode * err)
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *mySource = args->source;
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *myTarget;
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *sourceLimit = args->sourceLimit;
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 ch, ch2;
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned int indexToWrite;
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char temp[sizeof(uint32_t)];
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mySource >= sourceLimit) {
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no input, nothing to do */
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* write the BOM if necessary */
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        static const char bom[]={ 0, 0, (char)0xfe, (char)0xff };
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_fromUWriteBytes(args->converter,
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             bom, 4,
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->target, args->targetLimit,
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->offsets, -1,
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             err);
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUnicodeStatus=0;
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myTarget = (unsigned char *) args->target;
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    temp[0] = 0;
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->fromUChar32) {
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->fromUChar32;
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUChar32 = 0;
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto lowsurogate;
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit) {
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = *(mySource++);
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if (U_IS_SURROGATE(ch)) {
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_IS_LEAD(ch)) {
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulowsurogate:
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (mySource < sourceLimit) {
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ch2 = *mySource;
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (U_IS_TRAIL(ch2)) {
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        mySource++;
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    else {
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        args->converter->fromUChar32 = ch;
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* ran out of source */
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->fromUChar32 = ch;
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (args->flush) {
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* this is an unmatched trail code unit (2nd surrogate) */
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* callback(illegal) */
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->fromUChar32 = ch;
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_ILLEGAL_CHAR_FOUND;
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[1] = (uint8_t) (ch >> 16 & 0x1F);
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[2] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[3] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++) {
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (myTarget < targetLimit) {
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = temp[indexToWrite];
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_BUFFER_OVERFLOW_ERROR;
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err)) {
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = (char *) myTarget;
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = mySource;
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args,
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                               UErrorCode * err)
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *mySource = args->source;
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *myTarget;
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t *myOffsets;
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *sourceLimit = args->sourceLimit;
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 ch, ch2;
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t offsetNum = 0;
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned int indexToWrite;
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char temp[sizeof(uint32_t)];
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mySource >= sourceLimit) {
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no input, nothing to do */
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* write the BOM if necessary */
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        static const char bom[]={ 0, 0, (char)0xfe, (char)0xff };
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_fromUWriteBytes(args->converter,
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             bom, 4,
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->target, args->targetLimit,
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->offsets, -1,
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             err);
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUnicodeStatus=0;
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myTarget = (unsigned char *) args->target;
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myOffsets = args->offsets;
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    temp[0] = 0;
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->fromUChar32) {
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->fromUChar32;
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUChar32 = 0;
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto lowsurogate;
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit) {
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = *(mySource++);
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
35683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if (U_IS_SURROGATE(ch)) {
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_IS_LEAD(ch)) {
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulowsurogate:
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (mySource < sourceLimit) {
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ch2 = *mySource;
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (U_IS_TRAIL(ch2)) {
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        mySource++;
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    else {
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        args->converter->fromUChar32 = ch;
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* ran out of source */
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->fromUChar32 = ch;
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (args->flush) {
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* this is an unmatched trail code unit (2nd surrogate) */
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* callback(illegal) */
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->fromUChar32 = ch;
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_ILLEGAL_CHAR_FOUND;
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[1] = (uint8_t) (ch >> 16 & 0x1F);
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[2] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[3] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++) {
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (myTarget < targetLimit) {
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = temp[indexToWrite];
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myOffsets++) = offsetNum;
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_BUFFER_OVERFLOW_ERROR;
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offsetNum = offsetNum + 1 + (temp[1] != 0);
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err)) {
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = (char *) myTarget;
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = mySource;
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->offsets = myOffsets;
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UChar32
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_getNextUChar_UTF32_BE(UConverterToUnicodeArgs* args,
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode* err)
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const uint8_t *mySource;
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 myUChar;
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t length;
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mySource = (const uint8_t *)args->source;
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource >= (const uint8_t *)args->sourceLimit)
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no input */
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_INDEX_OUTOFBOUNDS_ERROR;
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0xffff;
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length = (int32_t)((const uint8_t *)args->sourceLimit - mySource);
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (length < 4)
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* got a partial character */
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memcpy(args->converter->toUBytes, mySource, length);
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toULength = (int8_t)length;
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->source = (const char *)(mySource + length);
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_TRUNCATED_CHAR_FOUND;
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0xffff;
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Don't even try to do a direct cast because the value may be on an odd address. */
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myUChar = ((UChar32)mySource[0] << 24)
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            | ((UChar32)mySource[1] << 16)
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            | ((UChar32)mySource[2] << 8)
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            | ((UChar32)mySource[3]);
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = (const char *)(mySource + 4);
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ((uint32_t)myUChar <= MAXIMUM_UTF && !U_IS_SURROGATE(myUChar)) {
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return myUChar;
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_memcpy(args->converter->toUBytes, mySource, 4);
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->converter->toULength = 4;
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *err = U_ILLEGAL_CHAR_FOUND;
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0xffff;
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterImpl _UTF32BEImpl = {
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_UTF32_BigEndian,
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_toUnicode_UTF32_BE,
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC,
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_BE,
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC,
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_getNextUChar_UTF32_BE,
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
48564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    ucnv_getNonSurrogateUnicodeSet,
48664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert
48764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    NULL,
48864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    NULL
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* The 1232 CCSID refers to any version of Unicode with any endianess of UTF-32 */
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterStaticData _UTF32BEStaticData = {
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    sizeof(UConverterStaticData),
494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "UTF-32BE",
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    1232,
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_IBM, UCNV_UTF32_BigEndian, 4, 4,
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0, 0, 0xff, 0xfd }, 4, FALSE, FALSE,
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0,
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0,
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
503c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertconst UConverterSharedData _UTF32BEData =
504c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_UTF32BEStaticData, &_UTF32BEImpl);
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* UTF-32LE ---------------------------------------------------------- */
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_toUnicode_UTF32_LE(UConverterToUnicodeArgs * args,
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                UErrorCode * err)
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *mySource = (unsigned char *) args->source;
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *myTarget = args->target;
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *targetLimit = args->targetLimit;
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *toUBytes = args->converter->toUBytes;
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t ch, i;
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Restore state of current sequence */
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = args->converter->toULength;       /* restore # of bytes consumed */
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toULength = 0;
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Stores the previously calculated ch from a previous call*/
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->toUnicodeStatus - 1;
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toUnicodeStatus = 0;
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto morebytes;
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit)
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = 0;
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = 0;
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querumorebytes:
536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (i < sizeof(uint32_t))
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (mySource < sourceLimit)
539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch |= ((uint8_t)(*mySource)) << (i * 8);
541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                toUBytes[i++] = (char) *(mySource++);
542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else
544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* stores a partially calculated target*/
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* + 1 to make 0 a valid character */
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toUnicodeStatus = ch + 1;
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toULength = (int8_t) i;
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto donefornow;
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch)) {
554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ch <= MAXIMUM_UCS2) {
556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* fits in 16 bits */
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = (UChar) ch;
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* write out the surrogates */
561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = U16_LEAD(ch);
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch = U16_TRAIL(ch);
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (myTarget < targetLimit) {
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *(myTarget++) = (UChar)ch;
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* Put in overflow buffer (not handled here) */
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBufferLength = 1;
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *err = U_BUFFER_OVERFLOW_ERROR;
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            args->converter->toULength = (int8_t)i;
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *err = U_ILLEGAL_CHAR_FOUND;
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudonefornow:
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* End of target buffer */
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = myTarget;
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = (const char *) mySource;
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC(UConverterToUnicodeArgs * args,
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                             UErrorCode * err)
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *mySource = (unsigned char *) args->source;
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *myTarget = args->target;
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t *myOffsets = args->offsets;
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *targetLimit = args->targetLimit;
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *toUBytes = args->converter->toUBytes;
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t ch, i;
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t offsetNum = 0;
605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Restore state of current sequence */
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = args->converter->toULength;       /* restore # of bytes consumed */
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toULength = 0;
611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Stores the previously calculated ch from a previous call*/
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->toUnicodeStatus - 1;
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toUnicodeStatus = 0;
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto morebytes;
616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit)
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = 0;
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = 0;
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querumorebytes:
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (i < sizeof(uint32_t))
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (mySource < sourceLimit)
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch |= ((uint8_t)(*mySource)) << (i * 8);
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                toUBytes[i++] = (char) *(mySource++);
629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else
631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* stores a partially calculated target*/
633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* + 1 to make 0 a valid character */
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toUnicodeStatus = ch + 1;
635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->toULength = (int8_t) i;
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                goto donefornow;
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch))
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ch <= MAXIMUM_UCS2)
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* fits in 16 bits */
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = (UChar) ch;
647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myOffsets++) = offsetNum;
648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* write out the surrogates */
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = U16_LEAD(ch);
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myOffsets++) = offsetNum;
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ch = U16_TRAIL(ch);
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (myTarget < targetLimit)
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                {
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *(myTarget++) = (UChar)ch;
657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *(myOffsets++) = offsetNum;
658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else
660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                {
661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* Put in overflow buffer (not handled here) */
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->UCharErrorBufferLength = 1;
664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    *err = U_BUFFER_OVERFLOW_ERROR;
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            args->converter->toULength = (int8_t)i;
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *err = U_ILLEGAL_CHAR_FOUND;
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offsetNum += i;
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudonefornow:
679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* End of target buffer */
682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = myTarget;
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = (const char *) mySource;
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->offsets = myOffsets;
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_fromUnicode_UTF32_LE(UConverterFromUnicodeArgs * args,
692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                  UErrorCode * err)
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *mySource = args->source;
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *myTarget;
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *sourceLimit = args->sourceLimit;
697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 ch, ch2;
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned int indexToWrite;
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char temp[sizeof(uint32_t)];
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mySource >= sourceLimit) {
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no input, nothing to do */
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* write the BOM if necessary */
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        static const char bom[]={ (char)0xff, (char)0xfe, 0, 0 };
710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_fromUWriteBytes(args->converter,
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             bom, 4,
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->target, args->targetLimit,
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->offsets, -1,
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             err);
715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUnicodeStatus=0;
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myTarget = (unsigned char *) args->target;
719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    temp[3] = 0;
720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->fromUChar32)
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->fromUChar32;
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUChar32 = 0;
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto lowsurogate;
726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit)
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = *(mySource++);
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
73283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if (U16_IS_SURROGATE(ch)) {
73383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            if (U16_IS_LEAD(ch))
734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulowsurogate:
736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (mySource < sourceLimit)
737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                {
738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ch2 = *mySource;
73983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius                    if (U16_IS_TRAIL(ch2)) {
740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        mySource++;
742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    else {
744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        args->converter->fromUChar32 = ch;
747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* ran out of source */
753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->fromUChar32 = ch;
754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (args->flush) {
755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* this is an unmatched trail code unit (2nd surrogate) */
764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* callback(illegal) */
765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->fromUChar32 = ch;
766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_ILLEGAL_CHAR_FOUND;
767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[2] = (uint8_t) (ch >> 16 & 0x1F);
773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[1] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[0] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++)
777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (myTarget < targetLimit)
779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = temp[indexToWrite];
781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else
783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_BUFFER_OVERFLOW_ERROR;
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = (char *) myTarget;
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = mySource;
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args,
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                               UErrorCode * err)
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *mySource = args->source;
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char *myTarget;
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t *myOffsets;
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *sourceLimit = args->sourceLimit;
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 ch, ch2;
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned int indexToWrite;
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    unsigned char temp[sizeof(uint32_t)];
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t offsetNum = 0;
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mySource >= sourceLimit) {
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no input, nothing to do */
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* write the BOM if necessary */
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        static const char bom[]={ (char)0xff, (char)0xfe, 0, 0 };
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_fromUWriteBytes(args->converter,
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             bom, 4,
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->target, args->targetLimit,
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             &args->offsets, -1,
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             err);
826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUnicodeStatus=0;
827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myTarget = (unsigned char *) args->target;
830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myOffsets = args->offsets;
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    temp[3] = 0;
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (args->converter->fromUChar32)
834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = args->converter->fromUChar32;
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->fromUChar32 = 0;
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        goto lowsurogate;
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while (mySource < sourceLimit && myTarget < targetLimit)
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ch = *(mySource++);
843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
84483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if (U16_IS_SURROGATE(ch)) {
84583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            if (U16_IS_LEAD(ch))
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulowsurogate:
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (mySource < sourceLimit)
849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                {
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ch2 = *mySource;
85183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius                    if (U16_IS_TRAIL(ch2))
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    {
853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        mySource++;
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    else {
857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        args->converter->fromUChar32 = ch;
860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* ran out of source */
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args->converter->fromUChar32 = ch;
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (args->flush) {
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* this is an unmatched trail code unit (2nd surrogate) */
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        /* callback(illegal) */
870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        *err = U_ILLEGAL_CHAR_FOUND;
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* this is an unmatched trail code unit (2nd surrogate) */
877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* callback(illegal) */
878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->fromUChar32 = ch;
879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_ILLEGAL_CHAR_FOUND;
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[2] = (uint8_t) (ch >> 16 & 0x1F);
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[1] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp[0] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++)
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (myTarget < targetLimit)
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myTarget++) = temp[indexToWrite];
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *(myOffsets++) = offsetNum;
895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *err = U_BUFFER_OVERFLOW_ERROR;
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offsetNum = offsetNum + 1 + (temp[2] != 0);
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_BUFFER_OVERFLOW_ERROR;
908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->target = (char *) myTarget;
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = mySource;
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->offsets = myOffsets;
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UChar32
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruT_UConverter_getNextUChar_UTF32_LE(UConverterToUnicodeArgs* args,
917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode* err)
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const uint8_t *mySource;
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32 myUChar;
921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t length;
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mySource = (const uint8_t *)args->source;
924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (mySource >= (const uint8_t *)args->sourceLimit)
925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* no input */
927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_INDEX_OUTOFBOUNDS_ERROR;
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0xffff;
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    length = (int32_t)((const uint8_t *)args->sourceLimit - mySource);
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (length < 4)
933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* got a partial character */
935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memcpy(args->converter->toUBytes, mySource, length);
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->converter->toULength = (int8_t)length;
937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        args->source = (const char *)(mySource + length);
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *err = U_TRUNCATED_CHAR_FOUND;
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0xffff;
940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Don't even try to do a direct cast because the value may be on an odd address. */
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    myUChar = ((UChar32)mySource[3] << 24)
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            | ((UChar32)mySource[2] << 16)
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            | ((UChar32)mySource[1] << 8)
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            | ((UChar32)mySource[0]);
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->source = (const char *)(mySource + 4);
949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ((uint32_t)myUChar <= MAXIMUM_UTF && !U_IS_SURROGATE(myUChar)) {
950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return myUChar;
951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_memcpy(args->converter->toUBytes, mySource, 4);
954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    args->converter->toULength = 4;
955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *err = U_ILLEGAL_CHAR_FOUND;
957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0xffff;
958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterImpl _UTF32LEImpl = {
961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_UTF32_LittleEndian,
962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_toUnicode_UTF32_LE,
971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC,
972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_LE,
973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC,
974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_getNextUChar_UTF32_LE,
975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
98064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    ucnv_getNonSurrogateUnicodeSet,
98164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert
98264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    NULL,
98364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    NULL
984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* The 1232 CCSID refers to any version of Unicode with any endianess of UTF-32 */
987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterStaticData _UTF32LEStaticData = {
988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    sizeof(UConverterStaticData),
989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "UTF-32LE",
990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    1234,
991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_IBM, UCNV_UTF32_LittleEndian, 4, 4,
992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0xfd, 0xff, 0, 0 }, 4, FALSE, FALSE,
993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0,
994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0,
995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
999c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertconst UConverterSharedData _UTF32LEData =
1000c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_UTF32LEStaticData, &_UTF32LEImpl);
1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* UTF-32 (Detect BOM) ------------------------------------------------------ */
1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Detect a BOM at the beginning of the stream and select UTF-32BE or UTF-32LE
1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * accordingly.
1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * State values:
1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 0    initial state
1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1    saw 00
1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2    saw 00 00
1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3    saw 00 00 FE
1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 4    -
1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 5    saw FF
1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 6    saw FF FE
1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 7    saw FF FE 00
1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 8    UTF-32BE mode
1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 9    UTF-32LE mode
1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * During detection: state&3==number of matching bytes so far.
1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * On output, emit U+FEFF as the first code point.
1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_UTF32Reset(UConverter *cnv, UConverterResetChoice choice) {
1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(choice<=UCNV_RESET_TO_UNICODE) {
1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* reset toUnicode: state=0 */
1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cnv->mode=0;
1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(choice!=UCNV_RESET_TO_UNICODE) {
1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* reset fromUnicode: prepare to output the UTF-32PE BOM */
1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cnv->fromUnicodeStatus=UCNV_NEED_TO_WRITE_BOM;
1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_UTF32Open(UConverter *cnv,
103985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           UConverterLoadArgs *pArgs,
1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           UErrorCode *pErrorCode) {
1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _UTF32Reset(cnv, UCNV_RESET_BOTH);
1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char utf32BOM[8]={ 0, 0, (char)0xfe, (char)0xff,    (char)0xff, (char)0xfe, 0, 0 };
1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void
1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_UTF32ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           UErrorCode *pErrorCode) {
1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UConverter *cnv=pArgs->converter;
1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *source=pArgs->source;
1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *sourceLimit=pArgs->sourceLimit;
1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t *offsets=pArgs->offsets;
1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t state, offsetDelta;
1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char b;
1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    state=cnv->mode;
1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*
1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * If we detect a BOM in this buffer, then we must add the BOM size to the
1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * offsets because the actual converter function will not see and count the BOM.
1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * offsetDelta will have the number of the BOM bytes that are in the current buffer.
1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    offsetDelta=0;
1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(source<sourceLimit && U_SUCCESS(*pErrorCode)) {
1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        switch(state) {
1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 0:
1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            b=*source;
1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(b==0) {
1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                state=1; /* could be 00 00 FE FF */
1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if(b==(char)0xff) {
1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                state=5; /* could be FF FE 00 00 */
1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                state=8; /* default to UTF-32BE */
1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                continue;
1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ++source;
1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 1:
1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 2:
1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 3:
1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 5:
1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 6:
1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 7:
1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(*source==utf32BOM[state]) {
1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++state;
1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++source;
1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(state==4) {
1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    state=8; /* detect UTF-32BE */
1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    offsetDelta=(int32_t)(source-pArgs->source);
1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else if(state==8) {
1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    state=9; /* detect UTF-32LE */
1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    offsetDelta=(int32_t)(source-pArgs->source);
1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* switch to UTF-32BE and pass the previous bytes */
1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                int32_t count=(int32_t)(source-pArgs->source); /* number of bytes from this buffer */
1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* reset the source */
1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                source=pArgs->source;
1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(count==(state&3)) {
1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* simple: all in the same buffer, just reset source */
1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    UBool oldFlush=pArgs->flush;
1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* some of the bytes are from a previous buffer, replay those first */
1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pArgs->source=utf32BOM+(state&4); /* select the correct BOM */
1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pArgs->sourceLimit=pArgs->source+((state&3)-count); /* replay previous bytes */
1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pArgs->flush=FALSE; /* this sourceLimit is not the real source stream limit */
1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* no offsets: bytes from previous buffer, and not enough for output */
1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* restore real pointers; pArgs->source will be set in case 8/9 */
1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pArgs->sourceLimit=sourceLimit;
1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pArgs->flush=oldFlush;
1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                state=8;
1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                continue;
1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 8:
1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* call UTF-32BE */
1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pArgs->source=source;
1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offsets==NULL) {
1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                T_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC(pArgs, pErrorCode);
1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            source=pArgs->source;
1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 9:
1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* call UTF-32LE */
1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pArgs->source=source;
1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(offsets==NULL) {
1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                T_UConverter_toUnicode_UTF32_LE(pArgs, pErrorCode);
1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                T_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC(pArgs, pErrorCode);
1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            source=pArgs->source;
1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        default:
1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break; /* does not occur */
1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* add BOM size to offsets - see comment at offsetDelta declaration */
1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(offsets!=NULL && offsetDelta!=0) {
1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t *offsetsLimit=pArgs->offsets;
1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while(offsets<offsetsLimit) {
1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *offsets++ += offsetDelta;
1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    pArgs->source=source;
1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(source==sourceLimit && pArgs->flush) {
1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* handle truncated input */
1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        switch(state) {
1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 0:
1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break; /* no input at all, nothing to do */
1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 8:
1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 9:
1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            T_UConverter_toUnicode_UTF32_LE(pArgs, pErrorCode);
1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        default:
1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* handle 0<state<8: call UTF-32BE with too-short input */
1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pArgs->source=utf32BOM+(state&4); /* select the correct BOM */
1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pArgs->sourceLimit=pArgs->source+(state&3); /* replay bytes */
1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* no offsets: not enough for output */
1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pArgs->source=source;
1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pArgs->sourceLimit=sourceLimit;
1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            state=8;
1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    cnv->mode=state;
1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UChar32
1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_UTF32GetNextUChar(UConverterToUnicodeArgs *pArgs,
1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   UErrorCode *pErrorCode) {
1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch(pArgs->converter->mode) {
1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case 8:
1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return T_UConverter_getNextUChar_UTF32_BE(pArgs, pErrorCode);
1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case 9:
1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return T_UConverter_getNextUChar_UTF32_LE(pArgs, pErrorCode);
1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    default:
1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return UCNV_GET_NEXT_UCHAR_USE_TO_U;
1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterImpl _UTF32Impl = {
1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_UTF32,
1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _UTF32Open,
1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _UTF32Reset,
1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _UTF32ToUnicodeWithOffsets,
1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _UTF32ToUnicodeWithOffsets,
1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_IS_BIG_ENDIAN
1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_BE,
1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC,
1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_LE,
1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    T_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC,
1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _UTF32GetNextUChar,
1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL, /* ### TODO implement getStarters for all Unicode encodings?! */
1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    NULL,
122564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    ucnv_getNonSurrogateUnicodeSet,
122664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert
122764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    NULL,
122864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert    NULL
1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* The 1236 CCSID refers to any version of Unicode with a BOM sensitive endianess of UTF-32 */
1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterStaticData _UTF32StaticData = {
1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    sizeof(UConverterStaticData),
1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "UTF-32",
1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    1236,
1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCNV_IBM, UCNV_UTF32, 4, 4,
1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_IS_BIG_ENDIAN
1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0, 0, 0xff, 0xfd }, 4,
1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0xfd, 0xff, 0, 0 }, 4,
1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    FALSE, FALSE,
1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0,
1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0,
1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1248c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertconst UConverterSharedData _UTF32Data =
1249c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_UTF32StaticData, &_UTF32Impl);
1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
1252