16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 2002-2011, International Business Machines
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Corporation and others.  All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   file name:  ucnv_u32.c
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   encoding:   US-ASCII
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   tab size:   8 (not used)
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   indentation:4
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created on: 2002jul01
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created by: Markus W. Scherer
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   UTF-32 converter implementation. Used to be in ucnv_utf.c.
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_CONVERSION
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucnv.h"
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf.h"
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_bld.h"
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_cnv.h"
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MAXIMUM_UCS2            0x0000FFFF
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MAXIMUM_UTF             0x0010FFFF
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HALF_SHIFT              10
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HALF_BASE               0x0010000
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HALF_MASK               0x3FF
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define SURROGATE_HIGH_START    0xD800
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define SURROGATE_LOW_START     0xDC00
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* -SURROGATE_LOW_START + HALF_BASE */
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define SURROGATE_LOW_BASE      9216
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgenum {
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_NEED_TO_WRITE_BOM=1
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UTF-32BE ----------------------------------------------------------------- */
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_toUnicode_UTF32_BE(UConverterToUnicodeArgs * args,
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                UErrorCode * err)
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *mySource = (unsigned char *) args->source;
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar *myTarget = args->target;
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *targetLimit = args->targetLimit;
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *toUBytes = args->converter->toUBytes;
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t ch, i;
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Restore state of current sequence */
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->toUnicodeStatus && myTarget < targetLimit) {
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = args->converter->toULength;       /* restore # of bytes consumed */
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toULength = 0;
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->toUnicodeStatus - 1;/*Stores the previously calculated ch from a previous call*/
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toUnicodeStatus = 0;
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto morebytes;
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit) {
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = 0;
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = 0;
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgmorebytes:
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while (i < sizeof(uint32_t)) {
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (mySource < sourceLimit) {
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch = (ch << 8) | (uint8_t)(*mySource);
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                toUBytes[i++] = (char) *(mySource++);
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* stores a partially calculated target*/
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* + 1 to make 0 a valid character */
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toUnicodeStatus = ch + 1;
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toULength = (int8_t) i;
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                goto donefornow;
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch)) {
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (ch <= MAXIMUM_UCS2)
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* fits in 16 bits */
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = (UChar) ch;
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* write out the surrogates */
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = U16_LEAD(ch);
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch = U16_TRAIL(ch);
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (myTarget < targetLimit) {
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *(myTarget++) = (UChar)ch;
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* Put in overflow buffer (not handled here) */
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBufferLength = 1;
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *err = U_BUFFER_OVERFLOW_ERROR;
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else {
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            args->converter->toULength = (int8_t)i;
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *err = U_ILLEGAL_CHAR_FOUND;
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdonefornow:
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err)) {
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* End of target buffer */
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = myTarget;
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = (const char *) mySource;
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC(UConverterToUnicodeArgs * args,
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             UErrorCode * err)
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *mySource = (unsigned char *) args->source;
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar *myTarget = args->target;
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t *myOffsets = args->offsets;
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *targetLimit = args->targetLimit;
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *toUBytes = args->converter->toUBytes;
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t ch, i;
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offsetNum = 0;
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Restore state of current sequence */
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->toUnicodeStatus && myTarget < targetLimit) {
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = args->converter->toULength;       /* restore # of bytes consumed */
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toULength = 0;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->toUnicodeStatus - 1;/*Stores the previously calculated ch from a previous call*/
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toUnicodeStatus = 0;
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto morebytes;
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit) {
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = 0;
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = 0;
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgmorebytes:
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while (i < sizeof(uint32_t)) {
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (mySource < sourceLimit) {
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch = (ch << 8) | (uint8_t)(*mySource);
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                toUBytes[i++] = (char) *(mySource++);
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* stores a partially calculated target*/
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* + 1 to make 0 a valid character */
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toUnicodeStatus = ch + 1;
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toULength = (int8_t) i;
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                goto donefornow;
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch)) {
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (ch <= MAXIMUM_UCS2) {
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* fits in 16 bits */
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = (UChar) ch;
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myOffsets++) = offsetNum;
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* write out the surrogates */
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = U16_LEAD(ch);
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *myOffsets++ = offsetNum;
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch = U16_TRAIL(ch);
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (myTarget < targetLimit)
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                {
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *(myTarget++) = (UChar)ch;
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *(myOffsets++) = offsetNum;
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* Put in overflow buffer (not handled here) */
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBufferLength = 1;
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *err = U_BUFFER_OVERFLOW_ERROR;
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else {
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            args->converter->toULength = (int8_t)i;
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *err = U_ILLEGAL_CHAR_FOUND;
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsetNum += i;
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdonefornow:
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* End of target buffer */
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = myTarget;
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = (const char *) mySource;
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->offsets = myOffsets;
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_fromUnicode_UTF32_BE(UConverterFromUnicodeArgs * args,
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UErrorCode * err)
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *mySource = args->source;
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *myTarget;
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *sourceLimit = args->sourceLimit;
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 ch, ch2;
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned int indexToWrite;
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char temp[sizeof(uint32_t)];
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(mySource >= sourceLimit) {
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no input, nothing to do */
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* write the BOM if necessary */
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        static const char bom[]={ 0, 0, (char)0xfe, (char)0xff };
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucnv_fromUWriteBytes(args->converter,
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             bom, 4,
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->target, args->targetLimit,
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->offsets, -1,
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             err);
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUnicodeStatus=0;
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myTarget = (unsigned char *) args->target;
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    temp[0] = 0;
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->fromUChar32) {
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->fromUChar32;
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUChar32 = 0;
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto lowsurogate;
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit) {
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = *(mySource++);
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_IS_SURROGATE(ch)) {
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_IS_LEAD(ch)) {
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orglowsurogate:
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (mySource < sourceLimit) {
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    ch2 = *mySource;
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (U_IS_TRAIL(ch2)) {
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        mySource++;
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    else {
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        args->converter->fromUChar32 = ch;
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        break;
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* ran out of source */
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->fromUChar32 = ch;
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (args->flush) {
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* this is an unmatched trail code unit (2nd surrogate) */
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* callback(illegal) */
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->fromUChar32 = ch;
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_ILLEGAL_CHAR_FOUND;
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[1] = (uint8_t) (ch >> 16 & 0x1F);
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[2] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[3] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++) {
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (myTarget < targetLimit) {
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = temp[indexToWrite];
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_BUFFER_OVERFLOW_ERROR;
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err)) {
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = (char *) myTarget;
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = mySource;
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args,
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UErrorCode * err)
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *mySource = args->source;
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *myTarget;
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t *myOffsets;
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *sourceLimit = args->sourceLimit;
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 ch, ch2;
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offsetNum = 0;
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned int indexToWrite;
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char temp[sizeof(uint32_t)];
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(mySource >= sourceLimit) {
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no input, nothing to do */
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* write the BOM if necessary */
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        static const char bom[]={ 0, 0, (char)0xfe, (char)0xff };
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucnv_fromUWriteBytes(args->converter,
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             bom, 4,
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->target, args->targetLimit,
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->offsets, -1,
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             err);
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUnicodeStatus=0;
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myTarget = (unsigned char *) args->target;
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myOffsets = args->offsets;
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    temp[0] = 0;
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->fromUChar32) {
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->fromUChar32;
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUChar32 = 0;
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto lowsurogate;
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit) {
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = *(mySource++);
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_IS_SURROGATE(ch)) {
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_IS_LEAD(ch)) {
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orglowsurogate:
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (mySource < sourceLimit) {
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    ch2 = *mySource;
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (U_IS_TRAIL(ch2)) {
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        mySource++;
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    else {
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        args->converter->fromUChar32 = ch;
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        break;
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* ran out of source */
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->fromUChar32 = ch;
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (args->flush) {
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* this is an unmatched trail code unit (2nd surrogate) */
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* callback(illegal) */
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->fromUChar32 = ch;
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_ILLEGAL_CHAR_FOUND;
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[1] = (uint8_t) (ch >> 16 & 0x1F);
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[2] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[3] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++) {
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (myTarget < targetLimit) {
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = temp[indexToWrite];
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myOffsets++) = offsetNum;
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_BUFFER_OVERFLOW_ERROR;
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsetNum = offsetNum + 1 + (temp[1] != 0);
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err)) {
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = (char *) myTarget;
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = mySource;
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->offsets = myOffsets;
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_getNextUChar_UTF32_BE(UConverterToUnicodeArgs* args,
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   UErrorCode* err)
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *mySource;
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 myUChar;
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t length;
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mySource = (const uint8_t *)args->source;
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource >= (const uint8_t *)args->sourceLimit)
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no input */
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_INDEX_OUTOFBOUNDS_ERROR;
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0xffff;
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    length = (int32_t)((const uint8_t *)args->sourceLimit - mySource);
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (length < 4)
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* got a partial character */
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_memcpy(args->converter->toUBytes, mySource, length);
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toULength = (int8_t)length;
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->source = (const char *)(mySource + length);
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_TRUNCATED_CHAR_FOUND;
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0xffff;
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Don't even try to do a direct cast because the value may be on an odd address. */
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myUChar = ((UChar32)mySource[0] << 24)
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            | ((UChar32)mySource[1] << 16)
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            | ((UChar32)mySource[2] << 8)
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            | ((UChar32)mySource[3]);
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = (const char *)(mySource + 4);
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if ((uint32_t)myUChar <= MAXIMUM_UTF && !U_IS_SURROGATE(myUChar)) {
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return myUChar;
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprv_memcpy(args->converter->toUBytes, mySource, 4);
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->converter->toULength = 4;
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *err = U_ILLEGAL_CHAR_FOUND;
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0xffff;
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UConverterImpl _UTF32BEImpl = {
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_UTF32_BigEndian,
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_toUnicode_UTF32_BE,
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC,
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_BE,
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC,
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_getNextUChar_UTF32_BE,
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucnv_getNonSurrogateUnicodeSet
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The 1232 CCSID refers to any version of Unicode with any endianess of UTF-32 */
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UConverterStaticData _UTF32BEStaticData = {
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sizeof(UConverterStaticData),
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    "UTF-32BE",
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    1232,
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_IBM, UCNV_UTF32_BigEndian, 4, 4,
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0, 0, 0xff, 0xfd }, 4, FALSE, FALSE,
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0,
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0,
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UConverterSharedData _UTF32BEData = {
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sizeof(UConverterSharedData), ~((uint32_t) 0),
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL, NULL, &_UTF32BEStaticData, FALSE, &_UTF32BEImpl,
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UTF-32LE ---------------------------------------------------------- */
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_toUnicode_UTF32_LE(UConverterToUnicodeArgs * args,
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                UErrorCode * err)
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *mySource = (unsigned char *) args->source;
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar *myTarget = args->target;
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *targetLimit = args->targetLimit;
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *toUBytes = args->converter->toUBytes;
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t ch, i;
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Restore state of current sequence */
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = args->converter->toULength;       /* restore # of bytes consumed */
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toULength = 0;
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Stores the previously calculated ch from a previous call*/
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->toUnicodeStatus - 1;
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toUnicodeStatus = 0;
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto morebytes;
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit)
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = 0;
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = 0;
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgmorebytes:
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while (i < sizeof(uint32_t))
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (mySource < sourceLimit)
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch |= ((uint8_t)(*mySource)) << (i * 8);
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                toUBytes[i++] = (char) *(mySource++);
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* stores a partially calculated target*/
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* + 1 to make 0 a valid character */
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toUnicodeStatus = ch + 1;
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toULength = (int8_t) i;
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                goto donefornow;
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch)) {
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (ch <= MAXIMUM_UCS2) {
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* fits in 16 bits */
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = (UChar) ch;
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* write out the surrogates */
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = U16_LEAD(ch);
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch = U16_TRAIL(ch);
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (myTarget < targetLimit) {
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *(myTarget++) = (UChar)ch;
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* Put in overflow buffer (not handled here) */
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBufferLength = 1;
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *err = U_BUFFER_OVERFLOW_ERROR;
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else {
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            args->converter->toULength = (int8_t)i;
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *err = U_ILLEGAL_CHAR_FOUND;
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdonefornow:
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* End of target buffer */
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = myTarget;
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = (const char *) mySource;
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC(UConverterToUnicodeArgs * args,
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             UErrorCode * err)
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *mySource = (unsigned char *) args->source;
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar *myTarget = args->target;
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t *myOffsets = args->offsets;
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *sourceLimit = (unsigned char *) args->sourceLimit;
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *targetLimit = args->targetLimit;
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *toUBytes = args->converter->toUBytes;
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t ch, i;
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offsetNum = 0;
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Restore state of current sequence */
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = args->converter->toULength;       /* restore # of bytes consumed */
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toULength = 0;
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Stores the previously calculated ch from a previous call*/
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->toUnicodeStatus - 1;
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toUnicodeStatus = 0;
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto morebytes;
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit)
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i = 0;
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = 0;
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgmorebytes:
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while (i < sizeof(uint32_t))
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (mySource < sourceLimit)
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch |= ((uint8_t)(*mySource)) << (i * 8);
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                toUBytes[i++] = (char) *(mySource++);
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* stores a partially calculated target*/
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* + 1 to make 0 a valid character */
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toUnicodeStatus = ch + 1;
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->toULength = (int8_t) i;
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                goto donefornow;
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (ch <= MAXIMUM_UTF && !U_IS_SURROGATE(ch))
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (ch <= MAXIMUM_UCS2)
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* fits in 16 bits */
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = (UChar) ch;
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myOffsets++) = offsetNum;
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* write out the surrogates */
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = U16_LEAD(ch);
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myOffsets++) = offsetNum;
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ch = U16_TRAIL(ch);
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (myTarget < targetLimit)
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                {
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *(myTarget++) = (UChar)ch;
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *(myOffsets++) = offsetNum;
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                {
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* Put in overflow buffer (not handled here) */
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBuffer[0] = (UChar) ch;
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->UCharErrorBufferLength = 1;
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *err = U_BUFFER_OVERFLOW_ERROR;
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            args->converter->toULength = (int8_t)i;
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *err = U_ILLEGAL_CHAR_FOUND;
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsetNum += i;
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdonefornow:
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* End of target buffer */
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = myTarget;
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = (const char *) mySource;
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->offsets = myOffsets;
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_fromUnicode_UTF32_LE(UConverterFromUnicodeArgs * args,
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UErrorCode * err)
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *mySource = args->source;
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *myTarget;
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *sourceLimit = args->sourceLimit;
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 ch, ch2;
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned int indexToWrite;
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char temp[sizeof(uint32_t)];
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(mySource >= sourceLimit) {
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no input, nothing to do */
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* write the BOM if necessary */
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        static const char bom[]={ (char)0xff, (char)0xfe, 0, 0 };
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucnv_fromUWriteBytes(args->converter,
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             bom, 4,
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->target, args->targetLimit,
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->offsets, -1,
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             err);
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUnicodeStatus=0;
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myTarget = (unsigned char *) args->target;
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    temp[3] = 0;
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->fromUChar32)
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->fromUChar32;
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUChar32 = 0;
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto lowsurogate;
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit)
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = *(mySource++);
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U16_IS_SURROGATE(ch)) {
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U16_IS_LEAD(ch))
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orglowsurogate:
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (mySource < sourceLimit)
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                {
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    ch2 = *mySource;
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (U16_IS_TRAIL(ch2)) {
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        mySource++;
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    else {
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        args->converter->fromUChar32 = ch;
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        break;
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* ran out of source */
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->fromUChar32 = ch;
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (args->flush) {
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* this is an unmatched trail code unit (2nd surrogate) */
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* callback(illegal) */
7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->fromUChar32 = ch;
7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_ILLEGAL_CHAR_FOUND;
7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[2] = (uint8_t) (ch >> 16 & 0x1F);
7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[1] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[0] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++)
7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (myTarget < targetLimit)
7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = temp[indexToWrite];
7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else
7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_BUFFER_OVERFLOW_ERROR;
7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = (char *) myTarget;
7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = mySource;
7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args,
7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UErrorCode * err)
8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *mySource = args->source;
8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char *myTarget;
8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t *myOffsets;
8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *sourceLimit = args->sourceLimit;
8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const unsigned char *targetLimit = (unsigned char *) args->targetLimit;
8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 ch, ch2;
8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned int indexToWrite;
8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unsigned char temp[sizeof(uint32_t)];
8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offsetNum = 0;
8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(mySource >= sourceLimit) {
8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no input, nothing to do */
8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* write the BOM if necessary */
8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        static const char bom[]={ (char)0xff, (char)0xfe, 0, 0 };
8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucnv_fromUWriteBytes(args->converter,
8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             bom, 4,
8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->target, args->targetLimit,
8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             &args->offsets, -1,
8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                             err);
8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUnicodeStatus=0;
8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myTarget = (unsigned char *) args->target;
8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myOffsets = args->offsets;
8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    temp[3] = 0;
8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (args->converter->fromUChar32)
8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = args->converter->fromUChar32;
8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->fromUChar32 = 0;
8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        goto lowsurogate;
8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while (mySource < sourceLimit && myTarget < targetLimit)
8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ch = *(mySource++);
8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U16_IS_SURROGATE(ch)) {
8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U16_IS_LEAD(ch))
8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orglowsurogate:
8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (mySource < sourceLimit)
8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                {
8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    ch2 = *mySource;
8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (U16_IS_TRAIL(ch2))
8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    {
8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        ch = ((ch - SURROGATE_HIGH_START) << HALF_SHIFT) + ch2 + SURROGATE_LOW_BASE;
8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        mySource++;
8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    else {
8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        args->converter->fromUChar32 = ch;
8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        break;
8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                else {
8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* ran out of source */
8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    args->converter->fromUChar32 = ch;
8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (args->flush) {
8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* this is an unmatched trail code unit (2nd surrogate) */
8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        /* callback(illegal) */
8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        *err = U_ILLEGAL_CHAR_FOUND;
8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else {
8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* this is an unmatched trail code unit (2nd surrogate) */
8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* callback(illegal) */
8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->fromUChar32 = ch;
8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_ILLEGAL_CHAR_FOUND;
8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[2] = (uint8_t) (ch >> 16 & 0x1F);
8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[1] = (uint8_t) (ch >> 8);  /* unsigned cast implicitly does (ch & FF) */
8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        temp[0] = (uint8_t) (ch);       /* unsigned cast implicitly does (ch & FF) */
8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (indexToWrite = 0; indexToWrite <= sizeof(uint32_t) - 1; indexToWrite++)
8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (myTarget < targetLimit)
8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myTarget++) = temp[indexToWrite];
8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *(myOffsets++) = offsetNum;
8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            else
8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            {
8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = temp[indexToWrite];
8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                *err = U_BUFFER_OVERFLOW_ERROR;
8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsetNum = offsetNum + 1 + (temp[2] != 0);
9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource < sourceLimit && myTarget >= targetLimit && U_SUCCESS(*err))
9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_BUFFER_OVERFLOW_ERROR;
9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->target = (char *) myTarget;
9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = mySource;
9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->offsets = myOffsets;
9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32
9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgT_UConverter_getNextUChar_UTF32_LE(UConverterToUnicodeArgs* args,
9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   UErrorCode* err)
9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *mySource;
9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 myUChar;
9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t length;
9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    mySource = (const uint8_t *)args->source;
9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (mySource >= (const uint8_t *)args->sourceLimit)
9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no input */
9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_INDEX_OUTOFBOUNDS_ERROR;
9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0xffff;
9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    length = (int32_t)((const uint8_t *)args->sourceLimit - mySource);
9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (length < 4)
9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* got a partial character */
9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_memcpy(args->converter->toUBytes, mySource, length);
9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->converter->toULength = (int8_t)length;
9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        args->source = (const char *)(mySource + length);
9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *err = U_TRUNCATED_CHAR_FOUND;
9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0xffff;
9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Don't even try to do a direct cast because the value may be on an odd address. */
9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    myUChar = ((UChar32)mySource[3] << 24)
9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            | ((UChar32)mySource[2] << 16)
9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            | ((UChar32)mySource[1] << 8)
9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            | ((UChar32)mySource[0]);
9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->source = (const char *)(mySource + 4);
9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if ((uint32_t)myUChar <= MAXIMUM_UTF && !U_IS_SURROGATE(myUChar)) {
9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return myUChar;
9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprv_memcpy(args->converter->toUBytes, mySource, 4);
9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    args->converter->toULength = 4;
9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *err = U_ILLEGAL_CHAR_FOUND;
9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0xffff;
9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UConverterImpl _UTF32LEImpl = {
9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_UTF32_LittleEndian,
9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_toUnicode_UTF32_LE,
9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC,
9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_LE,
9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC,
9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_getNextUChar_UTF32_LE,
9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucnv_getNonSurrogateUnicodeSet
9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The 1232 CCSID refers to any version of Unicode with any endianess of UTF-32 */
9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UConverterStaticData _UTF32LEStaticData = {
9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sizeof(UConverterStaticData),
9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    "UTF-32LE",
9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    1234,
9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_IBM, UCNV_UTF32_LittleEndian, 4, 4,
9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0xfd, 0xff, 0, 0 }, 4, FALSE, FALSE,
9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0,
9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0,
9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UConverterSharedData _UTF32LEData = {
9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sizeof(UConverterSharedData), ~((uint32_t) 0),
9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL, NULL, &_UTF32LEStaticData, FALSE, &_UTF32LEImpl,
9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0
9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UTF-32 (Detect BOM) ------------------------------------------------------ */
10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Detect a BOM at the beginning of the stream and select UTF-32BE or UTF-32LE
10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * accordingly.
10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * State values:
10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 0    initial state
10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1    saw 00
10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2    saw 00 00
10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3    saw 00 00 FE
10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4    -
10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 5    saw FF
10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 6    saw FF FE
10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 7    saw FF FE 00
10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8    UTF-32BE mode
10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9    UTF-32LE mode
10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * During detection: state&3==number of matching bytes so far.
10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * On output, emit U+FEFF as the first code point.
10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_UTF32Reset(UConverter *cnv, UConverterResetChoice choice) {
10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(choice<=UCNV_RESET_TO_UNICODE) {
10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* reset toUnicode: state=0 */
10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        cnv->mode=0;
10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(choice!=UCNV_RESET_TO_UNICODE) {
10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* reset fromUnicode: prepare to output the UTF-32PE BOM */
10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        cnv->fromUnicodeStatus=UCNV_NEED_TO_WRITE_BOM;
10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_UTF32Open(UConverter *cnv,
10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UConverterLoadArgs *pArgs,
10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *pErrorCode) {
10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    _UTF32Reset(cnv, UCNV_RESET_BOTH);
10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char utf32BOM[8]={ 0, 0, (char)0xfe, (char)0xff,    (char)0xff, (char)0xfe, 0, 0 };
10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_UTF32ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                           UErrorCode *pErrorCode) {
10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UConverter *cnv=pArgs->converter;
10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const char *source=pArgs->source;
10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const char *sourceLimit=pArgs->sourceLimit;
10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t *offsets=pArgs->offsets;
10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t state, offsetDelta;
10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    char b;
10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    state=cnv->mode;
10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * If we detect a BOM in this buffer, then we must add the BOM size to the
10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * offsets because the actual converter function will not see and count the BOM.
10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * offsetDelta will have the number of the BOM bytes that are in the current buffer.
10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsetDelta=0;
10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while(source<sourceLimit && U_SUCCESS(*pErrorCode)) {
10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch(state) {
10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 0:
10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            b=*source;
10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(b==0) {
10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                state=1; /* could be 00 00 FE FF */
10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else if(b==(char)0xff) {
10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                state=5; /* could be FF FE 00 00 */
10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                state=8; /* default to UTF-32BE */
10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                continue;
10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ++source;
10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 1:
10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 2:
10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 3:
10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 5:
10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 6:
10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 7:
10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(*source==utf32BOM[state]) {
10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++state;
10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++source;
10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(state==4) {
10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    state=8; /* detect UTF-32BE */
10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    offsetDelta=(int32_t)(source-pArgs->source);
10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                } else if(state==8) {
10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    state=9; /* detect UTF-32LE */
10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    offsetDelta=(int32_t)(source-pArgs->source);
10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* switch to UTF-32BE and pass the previous bytes */
10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                int32_t count=(int32_t)(source-pArgs->source); /* number of bytes from this buffer */
10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* reset the source */
10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                source=pArgs->source;
11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(count==(state&3)) {
11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* simple: all in the same buffer, just reset source */
11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                } else {
11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    UBool oldFlush=pArgs->flush;
11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* some of the bytes are from a previous buffer, replay those first */
11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    pArgs->source=utf32BOM+(state&4); /* select the correct BOM */
11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    pArgs->sourceLimit=pArgs->source+((state&3)-count); /* replay previous bytes */
11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    pArgs->flush=FALSE; /* this sourceLimit is not the real source stream limit */
11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* no offsets: bytes from previous buffer, and not enough for output */
11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    /* restore real pointers; pArgs->source will be set in case 8/9 */
11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    pArgs->sourceLimit=sourceLimit;
11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    pArgs->flush=oldFlush;
11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                state=8;
11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                continue;
11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 8:
11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* call UTF-32BE */
11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pArgs->source=source;
11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(offsets==NULL) {
11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                T_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC(pArgs, pErrorCode);
11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            source=pArgs->source;
11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 9:
11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* call UTF-32LE */
11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pArgs->source=source;
11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(offsets==NULL) {
11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                T_UConverter_toUnicode_UTF32_LE(pArgs, pErrorCode);
11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                T_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC(pArgs, pErrorCode);
11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            source=pArgs->source;
11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break; /* does not occur */
11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* add BOM size to offsets - see comment at offsetDelta declaration */
11486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(offsets!=NULL && offsetDelta!=0) {
11496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t *offsetsLimit=pArgs->offsets;
11506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while(offsets<offsetsLimit) {
11516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *offsets++ += offsetDelta;
11526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pArgs->source=source;
11566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(source==sourceLimit && pArgs->flush) {
11586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* handle truncated input */
11596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch(state) {
11606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 0:
11616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break; /* no input at all, nothing to do */
11626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 8:
11636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
11646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
11656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case 9:
11666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            T_UConverter_toUnicode_UTF32_LE(pArgs, pErrorCode);
11676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
11686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
11696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* handle 0<state<8: call UTF-32BE with too-short input */
11706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pArgs->source=utf32BOM+(state&4); /* select the correct BOM */
11716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pArgs->sourceLimit=pArgs->source+(state&3); /* replay bytes */
11726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* no offsets: not enough for output */
11746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            T_UConverter_toUnicode_UTF32_BE(pArgs, pErrorCode);
11756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pArgs->source=source;
11766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pArgs->sourceLimit=sourceLimit;
11776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            state=8;
11786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
11796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    cnv->mode=state;
11836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
11846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32
11866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_UTF32GetNextUChar(UConverterToUnicodeArgs *pArgs,
11876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                   UErrorCode *pErrorCode) {
11886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(pArgs->converter->mode) {
11896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case 8:
11906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return T_UConverter_getNextUChar_UTF32_BE(pArgs, pErrorCode);
11916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case 9:
11926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return T_UConverter_getNextUChar_UTF32_LE(pArgs, pErrorCode);
11936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
11946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return UCNV_GET_NEXT_UCHAR_USE_TO_U;
11956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
11976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UConverterImpl _UTF32Impl = {
11996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_UTF32,
12006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
12026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
12036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    _UTF32Open,
12056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
12066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    _UTF32Reset,
12076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    _UTF32ToUnicodeWithOffsets,
12096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    _UTF32ToUnicodeWithOffsets,
12106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if U_IS_BIG_ENDIAN
12116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_BE,
12126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC,
12136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
12146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_LE,
12156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    T_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC,
12166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
12176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    _UTF32GetNextUChar,
12186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL, /* ### TODO implement getStarters for all Unicode encodings?! */
12206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
12216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
12226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
12236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucnv_getNonSurrogateUnicodeSet
12246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
12256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The 1236 CCSID refers to any version of Unicode with a BOM sensitive endianess of UTF-32 */
12276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UConverterStaticData _UTF32StaticData = {
12286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sizeof(UConverterStaticData),
12296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    "UTF-32",
12306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    1236,
12316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCNV_IBM, UCNV_UTF32, 4, 4,
12326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if U_IS_BIG_ENDIAN
12336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0, 0, 0xff, 0xfd }, 4,
12346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
12356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0xfd, 0xff, 0, 0 }, 4,
12366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
12376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    FALSE, FALSE,
12386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0,
12396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0,
12406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
12416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
12426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UConverterSharedData _UTF32Data = {
12446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    sizeof(UConverterSharedData), ~((uint32_t) 0),
12456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL, NULL, &_UTF32StaticData, FALSE, &_UTF32Impl,
12466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0
12476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
12486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
12496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1250