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