1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 459d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1998-2013, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* ucnv.c: 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Implements APIs for the ICU's codeset conversion library; 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* mostly calls through internal functions; 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by Bertrand A. Damiba 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History: 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 04/04/99 helena Fixed internal header inclusion. 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 05/09/00 helena Added implementation to handle fallback mappings. 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 06/20/2000 helena OS/400 port changes; mostly typecast. 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_CONVERSION 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv_err.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uset.h" 30103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf.h" 31103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h" 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "putilimp.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "utracimp.h" 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustr_imp.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_imp.h" 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_cnv.h" 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_bld.h" 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* size of intermediate and preflighting buffers in ucnv_convert() */ 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CHUNK_SIZE 1024 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct UAmbiguousConverter { 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name; 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar variant5c; 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} UAmbiguousConverter; 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UAmbiguousConverter ambiguousConverters[]={ 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-897_P100-1995", 0xa5 }, 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-942_P120-1999", 0xa5 }, 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-943_P130-1999", 0xa5 }, 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-946_P100-1995", 0xa5 }, 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-33722_P120-1999", 0xa5 }, 5627f654740f2a26ad62a5c155af9199af9e69b889claireho { "ibm-1041_P100-1995", 0xa5 }, 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*{ "ibm-54191_P100-2006", 0xa5 },*/ 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*{ "ibm-62383_P100-2007", 0xa5 },*/ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*{ "ibm-891_P100-1995", 0x20a9 },*/ 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-944_P100-1995", 0x20a9 }, 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-949_P110-1999", 0x20a9 }, 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "ibm-1363_P110-1997", 0x20a9 }, 6327f654740f2a26ad62a5c155af9199af9e69b889claireho { "ISO_2022,locale=ko,version=0", 0x20a9 }, 6427f654740f2a26ad62a5c155af9199af9e69b889claireho { "ibm-1088_P100-1995", 0x20a9 } 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Calls through createConverter */ 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverter* U_EXPORT2 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_open (const char *name, 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *r; 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (err == NULL || U_FAILURE (*err)) { 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru r = ucnv_createConverter(NULL, name, err); 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return r; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverter* U_EXPORT2 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_openPackage (const char *packageName, const char *converterName, UErrorCode * err) 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_createConverterFromPackage(packageName, converterName, err); 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Extracts the UChar* to a char* and calls through createConverter */ 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverter* U_EXPORT2 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_openU (const UChar * name, 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char asciiName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (err == NULL || U_FAILURE(*err)) 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (name == NULL) 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_open (NULL, err); 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (u_strlen(name) >= UCNV_MAX_CONVERTER_NAME_LENGTH) 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_open(u_austrcpy(asciiName, name), err); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Copy the string that is represented by the UConverterPlatform enum 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param platformString An output buffer 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param platform An enum representing a platform 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the length of the copied string. 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_copyPlatformString(char *platformString, UConverterPlatform pltfrm) 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (pltfrm) 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UCNV_IBM: 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_strcpy(platformString, "ibm-"); 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 4; 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UCNV_UNKNOWN: 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* default to empty string */ 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *platformString = 0; 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Assumes a $platform-#codepage.$CONVERTER_FILE_EXTENSION scheme and calls 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *through createConverter*/ 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverter* U_EXPORT2 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_openCCSID (int32_t codepage, 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterPlatform platform, 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char myName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t myNameLen; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (err == NULL || U_FAILURE (*err)) 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* ucnv_copyPlatformString could return "ibm-" or "cp" */ 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myNameLen = ucnv_copyPlatformString(myName, platform); 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru T_CString_integerToString(myName + myNameLen, codepage, 10); 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_createConverter(NULL, myName, err); 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Creating a temporary stack-based object that can be used in one thread, 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruand created from a converter that is shared across threads. 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverter* U_EXPORT2 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status) 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *localConverter, *allocatedConverter; 15759d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t stackBufferSize; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t bufferSizeNeeded; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *stackBufferChars = (char *)stackBuffer; 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode cbErr; 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUnicodeArgs toUArgs = { 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(UConverterToUnicodeArgs), 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }; 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUnicodeArgs fromUArgs = { 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(UConverterFromUnicodeArgs), 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }; 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_CLONE); 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (status == NULL || U_FAILURE(*status)){ 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(status? *status: U_ILLEGAL_ARGUMENT_ERROR); 18659d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18959d709d503bab6e2b61931737e662dd293b40578ccornelius if (cnv == NULL) { 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*status); 19259d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA3(UTRACE_OPEN_CLOSE, "clone converter %s at %p into stackBuffer %p", 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_getName(cnv, status), cnv, stackBuffer); 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->sharedData->impl->safeClone != NULL) { 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the custom safeClone function for sizing */ 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bufferSizeNeeded = 0; 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->sharedData->impl->safeClone(cnv, NULL, &bufferSizeNeeded, status); 20259d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(*status)) { 20359d709d503bab6e2b61931737e662dd293b40578ccornelius UTRACE_EXIT_STATUS(*status); 20459d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 20559d709d503bab6e2b61931737e662dd293b40578ccornelius } 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* inherent sizing */ 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bufferSizeNeeded = sizeof(UConverter); 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21359d709d503bab6e2b61931737e662dd293b40578ccornelius if (pBufferSize == NULL) { 21459d709d503bab6e2b61931737e662dd293b40578ccornelius stackBufferSize = 1; 21559d709d503bab6e2b61931737e662dd293b40578ccornelius pBufferSize = &stackBufferSize; 21659d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 21759d709d503bab6e2b61931737e662dd293b40578ccornelius stackBufferSize = *pBufferSize; 21859d709d503bab6e2b61931737e662dd293b40578ccornelius if (stackBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */ 21959d709d503bab6e2b61931737e662dd293b40578ccornelius *pBufferSize = bufferSizeNeeded; 22059d709d503bab6e2b61931737e662dd293b40578ccornelius UTRACE_EXIT_VALUE(bufferSizeNeeded); 22159d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 22259d709d503bab6e2b61931737e662dd293b40578ccornelius } 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Pointers on 64-bit platforms need to be aligned 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * on a 64-bit boundary in memory. 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) { 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars); 23159d709d503bab6e2b61931737e662dd293b40578ccornelius if(stackBufferSize > offsetUp) { 23259d709d503bab6e2b61931737e662dd293b40578ccornelius stackBufferSize -= offsetUp; 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru stackBufferChars += offsetUp; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */ 23659d709d503bab6e2b61931737e662dd293b40578ccornelius stackBufferSize = 1; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru stackBuffer = (void *)stackBufferChars; 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Now, see if we must allocate any memory */ 24359d709d503bab6e2b61931737e662dd293b40578ccornelius if (stackBufferSize < bufferSizeNeeded || stackBuffer == NULL) 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allocate one here...*/ 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter = allocatedConverter = (UConverter *) uprv_malloc (bufferSizeNeeded); 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(localConverter == NULL) { 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*status); 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 25359d709d503bab6e2b61931737e662dd293b40578ccornelius *status = U_SAFECLONE_ALLOCATED_WARNING; 25459d709d503bab6e2b61931737e662dd293b40578ccornelius 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* record the fact that memory was allocated */ 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pBufferSize = bufferSizeNeeded; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* just use the stack buffer */ 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter = (UConverter*) stackBuffer; 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru allocatedConverter = NULL; 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(localConverter, 0, bufferSizeNeeded); 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Copy initial state */ 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(localConverter, cnv, sizeof(UConverter)); 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter->isCopyLocal = localConverter->isExtraLocal = FALSE; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the substitution string */ 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->subChars == (uint8_t *)cnv->subUChars) { 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter->subChars = (uint8_t *)localConverter->subUChars; 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter->subChars = (uint8_t *)uprv_malloc(UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localConverter->subChars == NULL) { 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(allocatedConverter); 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*status); 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(localConverter->subChars, cnv->subChars, UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* now either call the safeclone fcn or not */ 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->sharedData->impl->safeClone != NULL) { 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the custom safeClone function */ 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter = cnv->sharedData->impl->safeClone(cnv, localConverter, pBufferSize, status); 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(localConverter==NULL || U_FAILURE(*status)) { 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (allocatedConverter != NULL && allocatedConverter->subChars != (uint8_t *)allocatedConverter->subUChars) { 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(allocatedConverter->subChars); 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(allocatedConverter); 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*status); 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* increment refcount of shared data if needed */ 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Checking whether it's an algorithic converter is okay 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in multithreaded applications because the value never changes. 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Don't check referenceCounter for any other value. 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->sharedData->referenceCounter != ~0) { 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_incrementRefCount(cnv->sharedData); 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(localConverter == (UConverter*)stackBuffer) { 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* we're using user provided data - set to not destroy */ 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverter->isCopyLocal = TRUE; 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allow callback functions to handle any memory allocation */ 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.converter = fromUArgs.converter = localConverter; 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cbErr = U_ZERO_ERROR; 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->fromCharErrorBehaviour(cnv->toUContext, &toUArgs, NULL, 0, UCNV_CLONE, &cbErr); 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cbErr = U_ZERO_ERROR; 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->fromUCharErrorBehaviour(cnv->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLONE, &cbErr); 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(localConverter, *status); 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return localConverter; 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Decreases the reference counter in the shared immutable section of the object 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *and frees the mutable part*/ 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_close (UConverter * converter) 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_CLOSE); 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter == NULL) 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT(); 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA3(UTRACE_OPEN_CLOSE, "close converter %s at %p, isCopyLocal=%b", 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_getName(converter, &errorCode), converter, converter->isCopyLocal); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* In order to speed up the close, only call the callbacks when they have been changed. 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This performance check will only work when the callbacks are set within a shared library 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru or from user code that statically links this code. */ 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* first, notify the callback functions that the converter is closed */ 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->fromCharErrorBehaviour != UCNV_TO_U_DEFAULT_CALLBACK) { 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUnicodeArgs toUArgs = { 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(UConverterToUnicodeArgs), 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.converter = converter; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode = U_ZERO_ERROR; 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_CLOSE, &errorCode); 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->fromUCharErrorBehaviour != UCNV_FROM_U_DEFAULT_CALLBACK) { 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUnicodeArgs fromUArgs = { 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(UConverterFromUnicodeArgs), 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }; 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.converter = converter; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode = U_ZERO_ERROR; 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLOSE, &errorCode); 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->sharedData->impl->close != NULL) { 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->sharedData->impl->close(converter); 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->subChars != (uint8_t *)converter->subUChars) { 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(converter->subChars); 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Checking whether it's an algorithic converter is okay 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in multithreaded applications because the value never changes. 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Don't check referenceCounter for any other value. 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->sharedData->referenceCounter != ~0) { 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_unloadSharedDataIfReady(converter->sharedData); 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!converter->isCopyLocal){ 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(converter); 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT(); 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*returns a single Name from the list, will return NULL if out of bounds 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getAvailableName (int32_t n) 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (0 <= n && n <= 0xffff) { 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name = ucnv_bld_getAvailableConverter((uint16_t)n, &err); 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(err)) { 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_countAvailable () 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_bld_countAvailableConverters(&err); 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getSubstChars (const UConverter * converter, 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *mySubChar, 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t * len, 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->subCharLen <= 0) { 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Unicode string or empty string from ucnv_setSubstString(). */ 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *len = 0; 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*len < converter->subCharLen) /*not enough space in subChars */ 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_INDEX_OUTOFBOUNDS_ERROR; 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy (mySubChar, converter->subChars, converter->subCharLen); /*fills in the subchars */ 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *len = converter->subCharLen; /*store # of bytes copied to buffer */ 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setSubstChars (UConverter * converter, 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *mySubChar, 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t len, 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*Makes sure that the subChar is within the codepages char length boundaries */ 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((len > converter->sharedData->staticData->maxBytesPerChar) 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || (len < converter->sharedData->staticData->minBytesPerChar)) 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy (converter->subChars, mySubChar, len); /*copies the subchars */ 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->subCharLen = len; /*sets the new len */ 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * There is currently (2001Feb) no separate API to set/get subChar1. 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In order to always have subChar written after it is explicitly set, 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * we set subChar1 to 0. 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->subChar1 = 0; 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setSubstString(UConverter *cnv, 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *s, 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length, 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UAlignedMemory cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE / sizeof(UAlignedMemory) + 1]; 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char chars[UCNV_ERROR_BUFFER_LENGTH]; 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *clone; 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t *subChars; 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cloneSize, length8; 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Let the following functions check all arguments. */ 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cloneSize = sizeof(cloneBuffer); 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clone = ucnv_safeClone(cnv, cloneBuffer, &cloneSize, err); 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_setFromUCallBack(clone, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, err); 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length8 = ucnv_fromUChars(clone, chars, (int32_t)sizeof(chars), s, length, err); 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(clone); 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->sharedData->impl->writeSub == NULL 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || (cnv->sharedData->staticData->conversionType == UCNV_MBCS && 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_MBCSGetType(cnv) != UCNV_EBCDIC_STATEFUL) 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The converter is not stateful. Store the charset bytes as a fixed string. */ 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru subChars = (uint8_t *)chars; 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The converter has a non-default writeSub() function, indicating 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that it is stateful. 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Store the Unicode string for on-the-fly conversion for correct 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * state handling. 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (length > UCNV_ERROR_BUFFER_LENGTH) { 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Should not occur. The converter should output at least one byte 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * per UChar, which means that ucnv_fromUChars() should catch all 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * overflows. 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_BUFFER_OVERFLOW_ERROR; 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru subChars = (uint8_t *)s; 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (length < 0) { 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length = u_strlen(s); 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length8 = length * U_SIZEOF_UCHAR; 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * For storing the substitution string, select either the small buffer inside 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * UConverter or allocate a subChars buffer. 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (length8 > UCNV_MAX_SUBCHAR_LEN) { 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Use a separate buffer for the string. Outside UConverter to not make it too large. */ 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->subChars == (uint8_t *)cnv->subUChars) { 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Allocate a new buffer for the string. */ 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->subChars = (uint8_t *)uprv_malloc(UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cnv->subChars == NULL) { 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->subChars = (uint8_t *)cnv->subUChars; 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_MEMORY_ALLOCATION_ERROR; 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(cnv->subChars, 0, UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Copy the substitution string into the UConverter or its subChars buffer. */ 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (length8 == 0) { 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->subCharLen = 0; 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(cnv->subChars, subChars, length8); 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (subChars == (uint8_t *)chars) { 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->subCharLen = (int8_t)length8; 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else /* subChars == s */ { 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->subCharLen = (int8_t)-length; 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* See comment in ucnv_setSubstChars(). */ 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->subChar1 = 0; 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*resets the internal states of a converter 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *goal : have the same behaviour than a freshly created converter 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void _reset(UConverter *converter, UConverterResetChoice choice, 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool callCallback) { 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(converter == NULL) { 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(callCallback) { 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* first, notify the callback functions that the converter is reset */ 57985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode errorCode; 58085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 58185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(choice<=UCNV_RESET_TO_UNICODE && converter->fromCharErrorBehaviour != UCNV_TO_U_DEFAULT_CALLBACK) { 58285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterToUnicodeArgs toUArgs = { 58385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho sizeof(UConverterToUnicodeArgs), 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL 59185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho }; 59285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho toUArgs.converter = converter; 59385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho errorCode = U_ZERO_ERROR; 59485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode); 59585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 59685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(choice!=UCNV_RESET_TO_UNICODE && converter->fromUCharErrorBehaviour != UCNV_FROM_U_DEFAULT_CALLBACK) { 59785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterFromUnicodeArgs fromUArgs = { 59885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho sizeof(UConverterFromUnicodeArgs), 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL 60685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho }; 60785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fromUArgs.converter = converter; 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode = U_ZERO_ERROR; 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode); 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* now reset the converter itself */ 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(choice<=UCNV_RESET_TO_UNICODE) { 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus; 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->mode = 0; 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->toULength = 0; 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->invalidCharLength = converter->UCharErrorBufferLength = 0; 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->preToULength = 0; 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(choice!=UCNV_RESET_TO_UNICODE) { 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromUnicodeStatus = 0; 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromUChar32 = 0; 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->invalidUCharLength = converter->charErrorBufferLength = 0; 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->preFromUFirstCP = U_SENTINEL; 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->preFromULength = 0; 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converter->sharedData->impl->reset != NULL) { 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the custom reset function */ 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->sharedData->impl->reset(converter, choice); 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_reset(UConverter *converter) 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(converter, UCNV_RESET_BOTH, TRUE); 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_resetToUnicode(UConverter *converter) 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(converter, UCNV_RESET_TO_UNICODE, TRUE); 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_resetFromUnicode(UConverter *converter) 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(converter, UCNV_RESET_FROM_UNICODE, TRUE); 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int8_t U_EXPORT2 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getMaxCharSize (const UConverter * converter) 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return converter->maxBytesPerUChar; 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int8_t U_EXPORT2 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getMinCharSize (const UConverter * converter) 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return converter->sharedData->staticData->minBytesPerChar; 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getName (const UConverter * converter, UErrorCode * err) 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(converter->sharedData->impl->getName){ 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char* temp= converter->sharedData->impl->getName(converter); 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(temp) 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return temp; 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return converter->sharedData->staticData->name; 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getCCSID(const UConverter * converter, 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ccsid; 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ccsid = converter->sharedData->staticData->codepage; 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ccsid == 0) { 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Rare case. This is for cases like gb18030, 6918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius which doesn't have an IBM canonical name, but does have an IBM alias. */ 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *standardName = ucnv_getStandardName(ucnv_getName(converter, err), "IBM", err); 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(*err) && standardName) { 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *ccsidStr = uprv_strchr(standardName, '-'); 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ccsidStr) { 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ccsid = (int32_t)atol(ccsidStr+1); /* +1 to skip '-' */ 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ccsid; 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverterPlatform U_EXPORT2 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getPlatform (const UConverter * converter, 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UCNV_UNKNOWN; 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UConverterPlatform)converter->sharedData->staticData->platform; 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_getToUCallBack (const UConverter * converter, 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUCallback *action, 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void **context) 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *action = converter->fromCharErrorBehaviour; 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *context = converter->toUContext; 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_getFromUCallBack (const UConverter * converter, 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUCallback *action, 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void **context) 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *action = converter->fromUCharErrorBehaviour; 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *context = converter->fromUContext; 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setToUCallBack (UConverter * converter, 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUCallback newAction, 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void* newContext, 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUCallback *oldAction, 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void** oldContext, 738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (oldAction) *oldAction = converter->fromCharErrorBehaviour; 743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromCharErrorBehaviour = newAction; 744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (oldContext) *oldContext = converter->toUContext; 745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->toUContext = newContext; 746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setFromUCallBack (UConverter * converter, 750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUCallback newAction, 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void* newContext, 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUCallback *oldAction, 753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void** oldContext, 754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) 757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (oldAction) *oldAction = converter->fromUCharErrorBehaviour; 759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromUCharErrorBehaviour = newAction; 760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (oldContext) *oldContext = converter->fromUContext; 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->fromUContext = newContext; 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_updateOffsets(int32_t *offsets, int32_t length, 766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t sourceIndex, int32_t errorInputLength) { 767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *limit; 768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t delta, offset; 769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceIndex>=0) { 771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * adjust each offset by adding the previous sourceIndex 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * minus the length of the input sequence that caused an 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * error, if any 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delta=sourceIndex-errorInputLength; 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set each offset to -1 because this conversion function 780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * does not handle offsets 781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delta=-1; 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit=offsets+length; 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(delta==0) { 787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* most common case, nothing to do */ 788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(delta>0) { 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* add the delta to each offset (but not if the offset is <0) */ 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(offsets<limit) { 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=*offsets; 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offset>=0) { 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *offsets=offset+delta; 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++offsets; 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else /* delta<0 */ { 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set each offset to -1 because this conversion function 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * does not handle offsets 801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * or the error input sequence started in a previous buffer 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(offsets<limit) { 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *offsets++=-1; 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_fromUnicode --------------------------------------------------------- */ 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Implementation note for m:n conversions 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * While collecting source units to find the longest match for m:n conversion, 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * some source units may need to be stored for a partial match. 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * When a second buffer does not yield a match on all of the previously stored 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * source units, then they must be "replayed", i.e., fed back into the converter. 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The code relies on the fact that replaying will not nest - 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * converting a replay buffer will not result in a replay. 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This is because a replay is necessary only after the _continuation_ of a 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * partial match failed, but a replay buffer is converted as a whole. 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It may result in some of its units being stored again for a partial match, 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * but there will not be a continuation _during_ the replay which could fail. 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It is conceivable that a callback function could call the converter 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * recursively in a way that causes another replay to be stored, but that 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * would be an error in the callback function. 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Such violations will cause assertion failures in a debug build, 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and wrong output, but they will not cause a crash. 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) { 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUnicode fromUnicode; 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv; 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *s; 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *t; 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *offsets; 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t sourceIndex; 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t errorInputLength; 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool converterSawEndOfInput, calledCallback; 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* variables for m:n conversion */ 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar replay[UCNV_EXT_MAX_UCHARS]; 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *realSource, *realSourceLimit; 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t realSourceIndex; 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool realFlush; 849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv=pArgs->converter; 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=pArgs->source; 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=pArgs->target; 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets=pArgs->offsets; 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the converter implementation function */ 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=0; 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets==NULL) { 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUnicode=cnv->sharedData->impl->fromUnicode; 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUnicode=cnv->sharedData->impl->fromUnicodeWithOffsets; 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fromUnicode==NULL) { 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is no WithOffsets implementation */ 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUnicode=cnv->sharedData->impl->fromUnicode; 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* we will write -1 for each offset */ 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=-1; 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->preFromULength>=0) { 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* normal mode */ 871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=NULL; 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* avoid compiler warnings - not otherwise necessary, and the values do not matter */ 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceLimit=NULL; 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realFlush=FALSE; 876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceIndex=0; 877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Previous m:n conversion stored source units from a partial match 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and failed to consume all of them. 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We need to "replay" them from a temporary buffer and convert them first. 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=pArgs->source; 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceLimit=pArgs->sourceLimit; 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realFlush=pArgs->flush; 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceIndex=sourceIndex; 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(replay, cnv->preFromU, -cnv->preFromULength*U_SIZEOF_UCHAR); 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=replay; 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=replay-cnv->preFromULength; 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=FALSE; 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=-1; 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->preFromULength=0; 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop for conversion and error handling 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop { 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * convert 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop { 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * update offsets 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * handle end of input 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * handle errors/call callback 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert */ 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUnicode(pArgs, err); 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set a flag for whether the converter 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * successfully processed the end of the input 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * need not check cnv->preFromULength==0 because a replay (<0) will cause 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s<sourceLimit before converterSawEndOfInput is checked 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterSawEndOfInput= 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (UBool)(U_SUCCESS(*err) && 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush && pArgs->source==pArgs->sourceLimit && 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->fromUChar32==0); 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error from ucnv_convertEx() */ 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterSawEndOfInput=FALSE; 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no callback called yet for this iteration */ 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru calledCallback=FALSE; 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no sourceIndex adjustment for conversion, only for callback output */ 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorInputLength=0; 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop for offsets and error handling 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * iterates at most 3 times: 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1. to clean up after the conversion function 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2. after the callback 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3. after the callback again if there was truncated input 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* update offsets if we write any */ 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length=(int32_t)(pArgs->target-t); 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0) { 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _updateOffsets(offsets, length, sourceIndex, errorInputLength); 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if a converter handles offsets and updates the offsets 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * pointer at the end, then pArgs->offset should not change 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * here; 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * however, some converters do not handle offsets at all 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (sourceIndex<0) or may not update the offsets pointer 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->offsets=offsets+=length; 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceIndex>=0) { 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex+=(int32_t)(pArgs->source-s); 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->preFromULength<0) { 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * switch the source to new replay units (cannot occur while replaying) 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * after offset handling and before end-of-input and callback handling 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(realSource==NULL) { 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=pArgs->source; 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceLimit=pArgs->sourceLimit; 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realFlush=pArgs->flush; 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceIndex=sourceIndex; 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(replay, cnv->preFromU, -cnv->preFromULength*U_SIZEOF_UCHAR); 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=replay; 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=replay-cnv->preFromULength; 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=FALSE; 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((sourceIndex+=cnv->preFromULength)<0) { 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=-1; 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->preFromULength=0; 986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* see implementation note before _fromUnicodeWithCallback() */ 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_ASSERT(realSource==NULL); 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_INTERNAL_PROGRAM_ERROR; 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* update pointers */ 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=pArgs->source; 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=pArgs->target; 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(s<pArgs->sourceLimit) { 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * continue with the conversion loop while there is still input left 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (continue converting by breaking out of only the inner loop) 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(realSource!=NULL) { 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* switch back from replaying to the real source and continue */ 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=realSource; 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=realSourceLimit; 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=realFlush; 1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=realSourceIndex; 1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=NULL; 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(pArgs->flush && cnv->fromUChar32!=0) { 1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the entire input stream is consumed 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and there is a partial, truncated input sequence left 1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* inject an error and continue with callback handling */ 1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_TRUNCATED_CHAR_FOUND; 1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru calledCallback=FALSE; /* new error condition */ 1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* input consumed */ 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pArgs->flush) { 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return to the conversion loop once more if the flush 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * flag is set and the conversion function has not 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * successfully processed the end of the input yet 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (continue converting by breaking out of only the inner loop) 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!converterSawEndOfInput) { 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset the converter without calling the callback function */ 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(cnv, UCNV_RESET_FROM_UNICODE, FALSE); 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* done successfully */ 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* U_FAILURE(*err) */ 1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode e; 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( calledCallback || 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (e=*err)==U_BUFFER_OVERFLOW_ERROR || 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (e!=U_INVALID_CHAR_FOUND && 1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e!=U_ILLEGAL_CHAR_FOUND && 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e!=U_TRUNCATED_CHAR_FOUND) 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the callback did not or cannot resolve the error: 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set output pointers and return 1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the check for buffer overflow is redundant but it is 1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a high-runner case and hopefully documents the intent 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * well 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if we were replaying, then the replay buffer must be 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * copied back into the UConverter 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and the real arguments must be restored 1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(realSource!=NULL) { 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length; 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_ASSERT(cnv->preFromULength==0); 1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=(int32_t)(pArgs->sourceLimit-pArgs->source); 1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0) { 1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(cnv->preFromU, pArgs->source, length*U_SIZEOF_UCHAR); 1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->preFromULength=(int8_t)-length; 1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=realSource; 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=realSourceLimit; 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=realFlush; 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* callback handling */ 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 codePoint; 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get and write the code point */ 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru codePoint=cnv->fromUChar32; 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorInputLength=0; 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U16_APPEND_UNSAFE(cnv->invalidUCharBuffer, errorInputLength, codePoint); 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->invalidUCharLength=(int8_t)errorInputLength; 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the converter state to deal with the next character */ 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->fromUChar32=0; 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the callback function */ 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->fromUCharErrorBehaviour(cnv->fromUContext, pArgs, 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->invalidUCharBuffer, errorInputLength, codePoint, 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err==U_INVALID_CHAR_FOUND ? UCNV_UNASSIGNED : UCNV_ILLEGAL, 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru err); 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop back to the offset handling 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * this flag will indicate after offset handling 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that a callback was called; 1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if the callback did not resolve the error, then we return 1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru calledCallback=TRUE; 1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Output the fromUnicode overflow buffer. 1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Call this function if(cnv->charErrorBufferLength>0). 1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return TRUE if overflow 1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_outputOverflowFromUnicode(UConverter *cnv, 1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char **target, const char *targetLimit, 1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t **pOffsets, 1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *offsets; 1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *overflow, *t; 1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, length; 1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=*target; 1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pOffsets!=NULL) { 1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets=*pOffsets; 1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets=NULL; 1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru overflow=(char *)cnv->charErrorBuffer; 1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=cnv->charErrorBufferLength; 1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(i<length) { 1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(t==targetLimit) { 1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the overflow buffer contains too much, keep the rest */ 1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t j=0; 1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru overflow[j++]=overflow[i++]; 1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(i<length); 1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->charErrorBufferLength=(int8_t)j; 1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=t; 1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pOffsets=offsets; 1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_BUFFER_OVERFLOW_ERROR; 1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the overflow contents to the target */ 1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *t++=overflow[i++]; 1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *offsets++=-1; /* no source index available for old output */ 1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the overflow buffer is completely copied to the target */ 1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->charErrorBufferLength=0; 1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=t; 1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pOffsets=offsets; 1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_fromUnicode(UConverter *cnv, 1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char **target, const char *targetLimit, 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar **source, const UChar *sourceLimit, 1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *offsets, 1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool flush, 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUnicodeArgs args; 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *s; 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *t; 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check parameters */ 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv==NULL || target==NULL || source==NULL) { 1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=*source; 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=*target; 1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((const void *)U_MAX_PTR(sourceLimit) == (const void *)sourceLimit) { 1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Prevent code from going into an infinite loop in case we do hit this 1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit. The limit pointer is expected to be on a UChar * boundary. 1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This also prevents the next argument check from failing. 1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLimit = (const UChar *)(((const char *)sourceLimit) - 1); 1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * All these conditions should never happen. 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1) Make sure that the limits are >= to the address source or target 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2) Make sure that the buffer sizes do not exceed the number range for 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * int32_t because some functions use the size (in units or bytes) 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * rather than comparing pointers, and because offsets are int32_t values. 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * size_t is guaranteed to be unsigned and large enough for the job. 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return with an error instead of adjusting the limits because we would 1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * not be able to maintain the semantics that either the source must be 1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * consumed or the target filled (unless an error occurs). 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * An adjustment would be targetLimit=t+0x7fffffff; for example. 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3) Make sure that the user didn't incorrectly cast a UChar * pointer 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to a char * pointer and provide an incomplete UChar code unit. 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (sourceLimit<s || targetLimit<t || 1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((size_t)(sourceLimit-s)>(size_t)0x3fffffff && sourceLimit>s) || 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) || 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (((const char *)sourceLimit-(const char *)s) & 1) != 0) 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* output the target overflow buffer */ 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( cnv->charErrorBufferLength>0 && 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_outputOverflowFromUnicode(cnv, target, targetLimit, &offsets, err) 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* U_BUFFER_OVERFLOW_ERROR */ 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* *target may have moved, therefore stop using t */ 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!flush && s==sourceLimit && cnv->preFromULength>=0) { 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the overflow buffer is emptied and there is no new input: we are done */ 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Do not simply return with a buffer overflow error if 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * !flush && t==targetLimit 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * because it is possible that the source will not generate any output. 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * For example, the skip callback may be called; 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * it does not output anything. 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* prepare the converter arguments */ 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.converter=cnv; 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.flush=flush; 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.offsets=offsets; 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.source=s; 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.sourceLimit=sourceLimit; 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.target=*target; 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.targetLimit=targetLimit; 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.size=sizeof(args); 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _fromUnicodeWithCallback(&args, err); 1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *source=args.source; 1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=args.target; 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_toUnicode() --------------------------------------------------------- */ 1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_toUnicodeWithCallback(UConverterToUnicodeArgs *pArgs, UErrorCode *err) { 1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUnicode toUnicode; 1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv; 1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *s; 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *t; 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *offsets; 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t sourceIndex; 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t errorInputLength; 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool converterSawEndOfInput, calledCallback; 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* variables for m:n conversion */ 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char replay[UCNV_EXT_MAX_BYTES]; 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *realSource, *realSourceLimit; 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t realSourceIndex; 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool realFlush; 1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv=pArgs->converter; 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=pArgs->source; 1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=pArgs->target; 1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets=pArgs->offsets; 1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the converter implementation function */ 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=0; 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets==NULL) { 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUnicode=cnv->sharedData->impl->toUnicode; 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUnicode=cnv->sharedData->impl->toUnicodeWithOffsets; 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(toUnicode==NULL) { 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is no WithOffsets implementation */ 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUnicode=cnv->sharedData->impl->toUnicode; 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* we will write -1 for each offset */ 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=-1; 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->preToULength>=0) { 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* normal mode */ 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=NULL; 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* avoid compiler warnings - not otherwise necessary, and the values do not matter */ 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceLimit=NULL; 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realFlush=FALSE; 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceIndex=0; 1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Previous m:n conversion stored source units from a partial match 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and failed to consume all of them. 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We need to "replay" them from a temporary buffer and convert them first. 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=pArgs->source; 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceLimit=pArgs->sourceLimit; 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realFlush=pArgs->flush; 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceIndex=sourceIndex; 1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(replay, cnv->preToU, -cnv->preToULength); 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=replay; 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=replay-cnv->preToULength; 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=FALSE; 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=-1; 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->preToULength=0; 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop for conversion and error handling 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop { 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * convert 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop { 1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * update offsets 1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * handle end of input 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * handle errors/call callback 1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert */ 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUnicode(pArgs, err); 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set a flag for whether the converter 1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * successfully processed the end of the input 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * need not check cnv->preToULength==0 because a replay (<0) will cause 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s<sourceLimit before converterSawEndOfInput is checked 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterSawEndOfInput= 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (UBool)(U_SUCCESS(*err) && 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush && pArgs->source==pArgs->sourceLimit && 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->toULength==0); 1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error from getNextUChar() or ucnv_convertEx() */ 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterSawEndOfInput=FALSE; 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no callback called yet for this iteration */ 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru calledCallback=FALSE; 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no sourceIndex adjustment for conversion, only for callback output */ 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorInputLength=0; 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop for offsets and error handling 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * iterates at most 3 times: 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1. to clean up after the conversion function 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2. after the callback 1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3. after the callback again if there was truncated input 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* update offsets if we write any */ 1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length=(int32_t)(pArgs->target-t); 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0) { 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _updateOffsets(offsets, length, sourceIndex, errorInputLength); 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if a converter handles offsets and updates the offsets 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * pointer at the end, then pArgs->offset should not change 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * here; 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * however, some converters do not handle offsets at all 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (sourceIndex<0) or may not update the offsets pointer 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->offsets=offsets+=length; 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceIndex>=0) { 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex+=(int32_t)(pArgs->source-s); 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->preToULength<0) { 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * switch the source to new replay units (cannot occur while replaying) 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * after offset handling and before end-of-input and callback handling 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(realSource==NULL) { 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=pArgs->source; 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceLimit=pArgs->sourceLimit; 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realFlush=pArgs->flush; 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSourceIndex=sourceIndex; 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(replay, cnv->preToU, -cnv->preToULength); 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=replay; 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=replay-cnv->preToULength; 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=FALSE; 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((sourceIndex+=cnv->preToULength)<0) { 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=-1; 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->preToULength=0; 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* see implementation note before _fromUnicodeWithCallback() */ 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_ASSERT(realSource==NULL); 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_INTERNAL_PROGRAM_ERROR; 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* update pointers */ 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=pArgs->source; 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=pArgs->target; 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(s<pArgs->sourceLimit) { 1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * continue with the conversion loop while there is still input left 1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (continue converting by breaking out of only the inner loop) 1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(realSource!=NULL) { 1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* switch back from replaying to the real source and continue */ 1451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=realSource; 1452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=realSourceLimit; 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=realFlush; 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceIndex=realSourceIndex; 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru realSource=NULL; 1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(pArgs->flush && cnv->toULength>0) { 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the entire input stream is consumed 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and there is a partial, truncated input sequence left 1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* inject an error and continue with callback handling */ 1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_TRUNCATED_CHAR_FOUND; 1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru calledCallback=FALSE; /* new error condition */ 1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* input consumed */ 1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pArgs->flush) { 1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return to the conversion loop once more if the flush 1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * flag is set and the conversion function has not 1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * successfully processed the end of the input yet 1474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (continue converting by breaking out of only the inner loop) 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!converterSawEndOfInput) { 1478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset the converter without calling the callback function */ 1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(cnv, UCNV_RESET_TO_UNICODE, FALSE); 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* done successfully */ 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* U_FAILURE(*err) */ 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode e; 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( calledCallback || 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (e=*err)==U_BUFFER_OVERFLOW_ERROR || 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (e!=U_INVALID_CHAR_FOUND && 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e!=U_ILLEGAL_CHAR_FOUND && 1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e!=U_TRUNCATED_CHAR_FOUND && 1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e!=U_ILLEGAL_ESCAPE_SEQUENCE && 1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e!=U_UNSUPPORTED_ESCAPE_SEQUENCE) 1501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the callback did not or cannot resolve the error: 1504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set output pointers and return 1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the check for buffer overflow is redundant but it is 1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a high-runner case and hopefully documents the intent 1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * well 1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if we were replaying, then the replay buffer must be 1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * copied back into the UConverter 1512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and the real arguments must be restored 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(realSource!=NULL) { 1515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length; 1516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_ASSERT(cnv->preToULength==0); 1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=(int32_t)(pArgs->sourceLimit-pArgs->source); 1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0) { 1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(cnv->preToU, pArgs->source, length); 1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->preToULength=(int8_t)-length; 1523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->source=realSource; 1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->sourceLimit=realSourceLimit; 1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pArgs->flush=realFlush; 1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy toUBytes[] to invalidCharBuffer[] */ 1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorInputLength=cnv->invalidCharLength=cnv->toULength; 1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(errorInputLength>0) { 1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(cnv->invalidCharBuffer, cnv->toUBytes, errorInputLength); 1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the converter state to deal with the next character */ 1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->toULength=0; 1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the callback function */ 154485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(cnv->toUCallbackReason==UCNV_ILLEGAL && *err==U_INVALID_CHAR_FOUND) { 154585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho cnv->toUCallbackReason = UCNV_UNASSIGNED; 154685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->fromCharErrorBehaviour(cnv->toUContext, pArgs, 1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->invalidCharBuffer, errorInputLength, 154985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho cnv->toUCallbackReason, 1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru err); 155185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho cnv->toUCallbackReason = UCNV_ILLEGAL; /* reset to default value */ 1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * loop back to the offset handling 1555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * this flag will indicate after offset handling 1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that a callback was called; 1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if the callback did not resolve the error, then we return 1559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru calledCallback=TRUE; 1561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Output the toUnicode overflow buffer. 1567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Call this function if(cnv->UCharErrorBufferLength>0). 1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return TRUE if overflow 1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_outputOverflowToUnicode(UConverter *cnv, 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar **target, const UChar *targetLimit, 1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t **pOffsets, 1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *offsets; 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *overflow, *t; 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, length; 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=*target; 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pOffsets!=NULL) { 1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets=*pOffsets; 1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets=NULL; 1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru overflow=cnv->UCharErrorBuffer; 1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=cnv->UCharErrorBufferLength; 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(i<length) { 1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(t==targetLimit) { 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the overflow buffer contains too much, keep the rest */ 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t j=0; 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru overflow[j++]=overflow[i++]; 1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(i<length); 1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBufferLength=(int8_t)j; 1599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=t; 1600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pOffsets=offsets; 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_BUFFER_OVERFLOW_ERROR; 1604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the overflow contents to the target */ 1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *t++=overflow[i++]; 1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *offsets++=-1; /* no source index available for old output */ 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the overflow buffer is completely copied to the target */ 1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBufferLength=0; 1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=t; 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(offsets!=NULL) { 1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pOffsets=offsets; 1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 1624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_toUnicode(UConverter *cnv, 1625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar **target, const UChar *targetLimit, 1626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char **source, const char *sourceLimit, 1627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *offsets, 1628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool flush, 1629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 1630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUnicodeArgs args; 1631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *s; 1632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *t; 1633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check parameters */ 1635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv==NULL || target==NULL || source==NULL) { 1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=*source; 1645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=*target; 1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((const void *)U_MAX_PTR(targetLimit) == (const void *)targetLimit) { 1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Prevent code from going into an infinite loop in case we do hit this 1650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit. The limit pointer is expected to be on a UChar * boundary. 1651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This also prevents the next argument check from failing. 1652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLimit = (const UChar *)(((const char *)targetLimit) - 1); 1654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * All these conditions should never happen. 1658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1) Make sure that the limits are >= to the address source or target 1660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2) Make sure that the buffer sizes do not exceed the number range for 1662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * int32_t because some functions use the size (in units or bytes) 1663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * rather than comparing pointers, and because offsets are int32_t values. 1664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * size_t is guaranteed to be unsigned and large enough for the job. 1666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return with an error instead of adjusting the limits because we would 1668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * not be able to maintain the semantics that either the source must be 1669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * consumed or the target filled (unless an error occurs). 1670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * An adjustment would be sourceLimit=t+0x7fffffff; for example. 1671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3) Make sure that the user didn't incorrectly cast a UChar * pointer 1673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to a char * pointer and provide an incomplete UChar code unit. 1674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (sourceLimit<s || targetLimit<t || 1676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s) || 1677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((size_t)(targetLimit-t)>(size_t)0x3fffffff && targetLimit>t) || 1678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (((const char *)targetLimit-(const char *)t) & 1) != 0 1679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* output the target overflow buffer */ 1685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( cnv->UCharErrorBufferLength>0 && 1686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_outputOverflowToUnicode(cnv, target, targetLimit, &offsets, err) 1687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* U_BUFFER_OVERFLOW_ERROR */ 1689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* *target may have moved, therefore stop using t */ 1692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!flush && s==sourceLimit && cnv->preToULength>=0) { 1694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the overflow buffer is emptied and there is no new input: we are done */ 1695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Do not simply return with a buffer overflow error if 1700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * !flush && t==targetLimit 1701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * because it is possible that the source will not generate any output. 1702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * For example, the skip callback may be called; 1703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * it does not output anything. 1704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* prepare the converter arguments */ 1707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.converter=cnv; 1708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.flush=flush; 1709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.offsets=offsets; 1710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.source=s; 1711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.sourceLimit=sourceLimit; 1712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.target=*target; 1713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.targetLimit=targetLimit; 1714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.size=sizeof(args); 1715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _toUnicodeWithCallback(&args, err); 1717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *source=args.source; 1719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=args.target; 1720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_to/fromUChars() ----------------------------------------------------- */ 1723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_fromUChars(UConverter *cnv, 1726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *dest, int32_t destCapacity, 1727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *src, int32_t srcLength, 1728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 1729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *srcLimit; 1730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *originalDest, *destLimit; 1731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t destLength; 1732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check arguments */ 1734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( cnv==NULL || 1739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destCapacity<0 || (destCapacity>0 && dest==NULL) || 1740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLength<-1 || (srcLength!=0 && src==NULL) 1741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* initialize */ 1747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_resetFromUnicode(cnv); 1748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru originalDest=dest; 1749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcLength==-1) { 1750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLength=u_strlen(src); 1751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcLength>0) { 1753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLimit=src+srcLength; 1754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLimit=dest+destCapacity; 1755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */ 1757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destLimit<dest || (destLimit==NULL && dest!=NULL)) { 1758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLimit=(char *)U_MAX_PTR(dest); 1759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* perform the conversion */ 1762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 1763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength=(int32_t)(dest-originalDest); 1764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if an overflow occurs, then get the preflighting length */ 1766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 1767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char buffer[1024]; 1768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLimit=buffer+sizeof(buffer); 1770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 1771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest=buffer; 1772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 1773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 1774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength+=(int32_t)(dest-buffer); 1775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR); 1776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength=0; 1779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateChars(originalDest, destCapacity, destLength, pErrorCode); 1782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_toUChars(UConverter *cnv, 1786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *dest, int32_t destCapacity, 1787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *src, int32_t srcLength, 1788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 1789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *srcLimit; 1790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *originalDest, *destLimit; 1791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t destLength; 1792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check arguments */ 1794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( cnv==NULL || 1799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destCapacity<0 || (destCapacity>0 && dest==NULL) || 1800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLength<-1 || (srcLength!=0 && src==NULL)) 1801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* initialize */ 1807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_resetToUnicode(cnv); 1808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru originalDest=dest; 1809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcLength==-1) { 1810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLength=(int32_t)uprv_strlen(src); 1811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcLength>0) { 1813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLimit=src+srcLength; 1814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLimit=dest+destCapacity; 1815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */ 1817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(destLimit<dest || (destLimit==NULL && dest!=NULL)) { 1818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLimit=(UChar *)U_MAX_PTR(dest); 1819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* perform the conversion */ 1822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 1823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength=(int32_t)(dest-originalDest); 1824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if an overflow occurs, then get the preflighting length */ 1826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) 1827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar buffer[1024]; 1829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLimit=buffer+sizeof(buffer)/U_SIZEOF_UCHAR; 1831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 1832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest=buffer; 1833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 1834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 1835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength+=(int32_t)(dest-buffer); 1836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR); 1838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destLength=0; 1841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateUChars(originalDest, destCapacity, destLength, pErrorCode); 1844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_getNextUChar() ------------------------------------------------------ */ 1847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UChar32 U_EXPORT2 1849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getNextUChar(UConverter *cnv, 1850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char **source, const char *sourceLimit, 1851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 1852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUnicodeArgs args; 1853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar buffer[U16_MAX_LENGTH]; 1854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *s; 1855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 c; 1856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, length; 1857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check parameters */ 1859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(err==NULL || U_FAILURE(*err)) { 1860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0xffff; 1861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv==NULL || source==NULL) { 1864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0xffff; 1866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=*source; 1869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceLimit<s) { 1870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0xffff; 1872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Make sure that the buffer sizes do not exceed the number range for 1876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * int32_t because some functions use the size (in units or bytes) 1877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * rather than comparing pointers, and because offsets are int32_t values. 1878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * size_t is guaranteed to be unsigned and large enough for the job. 1880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return with an error instead of adjusting the limits because we would 1882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * not be able to maintain the semantics that either the source must be 1883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * consumed or the target filled (unless an error occurs). 1884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * An adjustment would be sourceLimit=t+0x7fffffff; for example. 1885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s)) { 1887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; 1888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0xffff; 1889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=U_SENTINEL; 1892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* flush the target overflow buffer */ 1894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->UCharErrorBufferLength>0) { 1895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *overflow; 1896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru overflow=cnv->UCharErrorBuffer; 1898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 1899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=cnv->UCharErrorBufferLength; 1900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U16_NEXT(overflow, i, length, c); 1901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move the remaining overflow contents up to the beginning */ 1903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((cnv->UCharErrorBufferLength=(int8_t)(length-i))>0) { 1904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memmove(cnv->UCharErrorBuffer, cnv->UCharErrorBuffer+i, 1905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBufferLength*U_SIZEOF_UCHAR); 1906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!U16_IS_LEAD(c) || i<length) { 1909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return c; 1910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Continue if the overflow buffer contained only a lead surrogate, 1913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * in case the converter outputs single surrogates from complete 1914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * input sequences. 1915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * flush==TRUE is implied for ucnv_getNextUChar() 1920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * do not simply return even if s==sourceLimit because the converter may 1922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * not have seen flush==TRUE before 1923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* prepare the converter arguments */ 1926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.converter=cnv; 1927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.flush=TRUE; 1928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.offsets=NULL; 1929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.source=s; 1930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.sourceLimit=sourceLimit; 1931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.target=buffer; 1932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.targetLimit=buffer+1; 1933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.size=sizeof(args); 1934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c<0) { 1936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * call the native getNextUChar() implementation if we are 1938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * at a character boundary (toULength==0) 1939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * unlike with _toUnicode(), getNextUChar() implementations must set 1941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * U_TRUNCATED_CHAR_FOUND for truncated input, 1942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * in addition to setting toULength/toUBytes[] 1943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->toULength==0 && cnv->sharedData->impl->getNextUChar!=NULL) { 1945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=cnv->sharedData->impl->getNextUChar(&args, err); 1946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *source=s=args.source; 1947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*err==U_INDEX_OUTOFBOUNDS_ERROR) { 1948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset the converter without calling the callback function */ 1949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(cnv, UCNV_RESET_TO_UNICODE, FALSE); 1950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0xffff; /* no output */ 1951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(U_SUCCESS(*err) && c>=0) { 1952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return c; 1953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * else fall through to use _toUnicode() because 1955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * UCNV_GET_NEXT_UCHAR_USE_TO_U: the native function did not want to handle it after all 1956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * U_FAILURE: call _toUnicode() for callback handling (do not output c) 1957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert to one UChar in buffer[0], or handle getNextUChar() errors */ 1962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _toUnicodeWithCallback(&args, err); 1963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*err==U_BUFFER_OVERFLOW_ERROR) { 1965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ZERO_ERROR; 1966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 1969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=(int32_t)(args.target-buffer); 1970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* write the lead surrogate from the overflow buffer */ 1972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buffer[0]=(UChar)c; 1973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.target=buffer+1; 1974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=0; 1975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=1; 1976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* buffer contents starts at i and ends before length */ 1979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) { 1981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=0xffff; /* no output */ 1982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(length==0) { 1983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no input or only state changes */ 1984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_INDEX_OUTOFBOUNDS_ERROR; 1985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no need to reset explicitly because _toUnicodeWithCallback() did it */ 1986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=0xffff; /* no output */ 1987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=buffer[0]; 1989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=1; 1990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!U16_IS_LEAD(c)) { 1991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* consume c=buffer[0], done */ 1992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* got a lead surrogate, see if a trail surrogate follows */ 1994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar c2; 1995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->UCharErrorBufferLength>0) { 1997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* got overflow output from the conversion */ 1998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U16_IS_TRAIL(c2=cnv->UCharErrorBuffer[0])) { 1999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* got a trail surrogate, too */ 2000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=U16_GET_SUPPLEMENTARY(c, c2); 2001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move the remaining overflow contents up to the beginning */ 2003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((--cnv->UCharErrorBufferLength)>0) { 2004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memmove(cnv->UCharErrorBuffer, cnv->UCharErrorBuffer+1, 2005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBufferLength*U_SIZEOF_UCHAR); 2006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* c is an unpaired lead surrogate, just return it */ 2009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(args.source<sourceLimit) { 2011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert once more, to buffer[1] */ 2012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args.targetLimit=buffer+2; 2013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _toUnicodeWithCallback(&args, err); 2014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*err==U_BUFFER_OVERFLOW_ERROR) { 2015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ZERO_ERROR; 2016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=(int32_t)(args.target-buffer); 2019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err) && length==2 && U16_IS_TRAIL(c2=buffer[1])) { 2020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* got a trail surrogate, too */ 2021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=U16_GET_SUPPLEMENTARY(c, c2); 2022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i=2; 2023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * move leftover output from buffer[i..length[ 2030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * into the beginning of the overflow buffer 2031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(i<length) { 2033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move further overflow back */ 2034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t delta=length-i; 2035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((length=cnv->UCharErrorBufferLength)>0) { 2036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memmove(cnv->UCharErrorBuffer+delta, cnv->UCharErrorBuffer, 2037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length*U_SIZEOF_UCHAR); 2038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBufferLength=(int8_t)(length+delta); 2040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBuffer[0]=buffer[i++]; 2042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(delta>1) { 2043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->UCharErrorBuffer[1]=buffer[i]; 2044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *source=args.source; 2048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return c; 2049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_convert() and siblings ---------------------------------------------- */ 2052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 2054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv, 2055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char **target, const char *targetLimit, 2056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char **source, const char *sourceLimit, 2057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *pivotStart, UChar **pivotSource, 2058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar **pivotTarget, const UChar *pivotLimit, 2059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool reset, UBool flush, 2060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 2061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar pivotBuffer[CHUNK_SIZE]; 2062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *myPivotSource; 2063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *myPivotTarget; 2064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *s; 2065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *t; 2066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterToUnicodeArgs toUArgs; 2068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterFromUnicodeArgs fromUArgs; 2069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterConvert convert; 2070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* error checking */ 2072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 2073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( targetCnv==NULL || sourceCnv==NULL || 2077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source==NULL || *source==NULL || 2078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru target==NULL || *target==NULL || targetLimit==NULL 2079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=*source; 2085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t=*target; 2086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((sourceLimit!=NULL && sourceLimit<s) || targetLimit<t) { 2087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Make sure that the buffer sizes do not exceed the number range for 2093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * int32_t. See ucnv_toUnicode() for a more detailed comment. 2094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( 2096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (sourceLimit!=NULL && ((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s)) || 2097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) 2098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pivotStart==NULL) { 2104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!flush) { 2105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* streaming conversion requires an explicit pivot buffer */ 2106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* use the stack pivot buffer */ 2111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myPivotSource=myPivotTarget=pivotStart=pivotBuffer; 2112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotSource=(UChar **)&myPivotSource; 2113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotTarget=&myPivotTarget; 2114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotLimit=pivotBuffer+CHUNK_SIZE; 2115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if( pivotStart>=pivotLimit || 2116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotSource==NULL || *pivotSource==NULL || 2117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotTarget==NULL || *pivotTarget==NULL || 2118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotLimit==NULL 2119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceLimit==NULL) { 2125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get limit of single-byte-NUL-terminated source string */ 2126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLimit=uprv_strchr(*source, 0); 2127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(reset) { 2130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_resetToUnicode(sourceCnv); 2131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_resetFromUnicode(targetCnv); 2132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pivotSource=*pivotTarget=pivotStart; 2133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(targetCnv->charErrorBufferLength>0) { 2134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* output the targetCnv overflow buffer */ 2135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ucnv_outputOverflowFromUnicode(targetCnv, target, targetLimit, NULL, pErrorCode)) { 2136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* U_BUFFER_OVERFLOW_ERROR */ 2137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* *target has moved, therefore stop using t */ 2140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( !flush && 2142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetCnv->preFromULength>=0 && *pivotSource==*pivotTarget && 2143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceCnv->UCharErrorBufferLength==0 && sourceCnv->preToULength>=0 && s==sourceLimit 2144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the fromUnicode overflow buffer is emptied and there is no new input: we are done */ 2146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Is direct-UTF-8 conversion available? */ 2151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( sourceCnv->sharedData->staticData->conversionType==UCNV_UTF8 && 2152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetCnv->sharedData->impl->fromUTF8!=NULL 2153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru convert=targetCnv->sharedData->impl->fromUTF8; 2155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if( targetCnv->sharedData->staticData->conversionType==UCNV_UTF8 && 2156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceCnv->sharedData->impl->toUTF8!=NULL 2157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru convert=sourceCnv->sharedData->impl->toUTF8; 2159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru convert=NULL; 2161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If direct-UTF-8 conversion is available, then we use a smaller 2165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * pivot buffer for error handling and partial matches 2166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * so that we quickly return to direct conversion. 2167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 32 is large enough for UCNV_EXT_MAX_UCHARS and UCNV_ERROR_BUFFER_LENGTH. 2169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We could reduce the pivot buffer size further, at the cost of 2171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * buffer overflows from callbacks. 2172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The pivot buffer should not be smaller than the maximum number of 2173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * fromUnicode extension table input UChars 2174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (for m:n conversion, see 2175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * targetCnv->sharedData->mbcs.extIndexes[UCNV_EXT_COUNT_UCHARS]) 2176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * or 2 for surrogate pairs. 2177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Too small a buffer can cause thrashing between pivoting and direct 2179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * conversion, with function call overhead outweighing the benefits 2180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * of direct conversion. 2181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(convert!=NULL && (pivotLimit-pivotStart)>32) { 2183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotLimit=pivotStart+32; 2184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* prepare the converter arguments */ 2187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.converter=targetCnv; 2188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.flush=FALSE; 2189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.offsets=NULL; 2190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.target=*target; 2191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.targetLimit=targetLimit; 2192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.size=sizeof(fromUArgs); 2193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.converter=sourceCnv; 2195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.flush=flush; 2196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.offsets=NULL; 2197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.source=s; 2198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.sourceLimit=sourceLimit; 2199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.targetLimit=pivotLimit; 2200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.size=sizeof(toUArgs); 2201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * TODO: Consider separating this function into two functions, 2204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * extracting exactly the conversion loop, 2205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * for readability and to reduce the set of visible variables. 2206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Otherwise stop using s and t from here on. 2208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=t=NULL; 2210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * conversion loop 2213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The sequence of steps in the loop may appear backward, 2215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * but the principle is simple: 2216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In the chain of 2217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * source - sourceCnv overflow - pivot - targetCnv overflow - target 2218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * empty out later buffers before refilling them from earlier ones. 2219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The targetCnv overflow buffer is flushed out only once before the loop. 2221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 2223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if(pivot not empty or error or replay or flush fromUnicode) { 2225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * fromUnicode(pivot -> target); 2226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 2227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * For pivoting conversion; and for direct conversion for 2229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * error callback handling and flushing the replay buffer. 2230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( *pivotSource<*pivotTarget || 2232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_FAILURE(*pErrorCode) || 2233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetCnv->preFromULength<0 || 2234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.flush 2235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.source=*pivotSource; 2237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.sourceLimit=*pivotTarget; 2238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _fromUnicodeWithCallback(&fromUArgs, pErrorCode); 2239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 2240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* target overflow, or conversion error */ 2241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pivotSource=(UChar *)fromUArgs.source; 2242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 2243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * _fromUnicodeWithCallback() must have consumed the pivot contents 2247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (*pivotSource==*pivotTarget) since it returned with U_SUCCESS() 2248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The pivot buffer is empty; reset it so we start at pivotStart. */ 2252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pivotSource=*pivotTarget=pivotStart; 2253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if(sourceCnv overflow buffer not empty) { 2256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * move(sourceCnv overflow buffer -> pivot); 2257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * continue; 2258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * } 2259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* output the sourceCnv overflow buffer */ 2261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceCnv->UCharErrorBufferLength>0) { 2262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ucnv_outputOverflowToUnicode(sourceCnv, pivotTarget, pivotLimit, NULL, pErrorCode)) { 2263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* U_BUFFER_OVERFLOW_ERROR */ 2264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 2265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; 2267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * check for end of input and break if done 2271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Checking both flush and fromUArgs.flush ensures that the converters 2273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * have been called with the flush flag set if the ucnv_convertEx() 2274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * caller set it. 2275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( toUArgs.source==sourceLimit && 2277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceCnv->preToULength>=0 && sourceCnv->toULength==0 && 2278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (!flush || fromUArgs.flush) 2279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* done successfully */ 2281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 2282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * use direct conversion if available 2286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * but not if continuing a partial match 2287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * or flushing the toUnicode replay buffer 2288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(convert!=NULL && targetCnv->preFromUFirstCP<0 && sourceCnv->preToULength==0) { 2290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_USING_DEFAULT_WARNING) { 2291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* remove a warning that may be set by this function */ 2292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 2293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru convert(&fromUArgs, &toUArgs, pErrorCode); 2295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 2296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 2297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(U_FAILURE(*pErrorCode)) { 2298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceCnv->toULength>0) { 2299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Fall through to calling _toUnicodeWithCallback() 2301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * for callback handling. 2302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The pivot buffer will be reset with 2304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * *pivotSource=*pivotTarget=pivotStart; 2305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * which indicates a toUnicode error to the caller 2306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (*pivotSource==pivotStart shows no pivot UChars consumed). 2307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Indicate a fromUnicode error to the caller 2311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * (*pivotSource>pivotStart shows some pivot UChars consumed). 2312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pivotSource=*pivotTarget=pivotStart+1; 2314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Loop around to calling _fromUnicodeWithCallbacks() 2316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * for callback handling. 2317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; 2319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(*pErrorCode==U_USING_DEFAULT_WARNING) { 2321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * No error, but the implementation requested to temporarily 2323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * fall back to pivoting. 2324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 2326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The following else branches are almost identical to the end-of-input 2328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * handling in _toUnicodeWithCallback(). 2329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Avoid calling it just for the end of input. 2330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(flush && sourceCnv->toULength>0) { /* flush==toUArgs.flush */ 2332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the entire input stream is consumed 2334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and there is a partial, truncated input sequence left 2335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* inject an error and continue with callback handling */ 2338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_TRUNCATED_CHAR_FOUND; 2339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* input consumed */ 2341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(flush) { 2342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset the converters without calling the callback functions */ 2343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(sourceCnv, UCNV_RESET_TO_UNICODE, FALSE); 2344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _reset(targetCnv, UCNV_RESET_FROM_UNICODE, FALSE); 2345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* done successfully */ 2348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 2349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * toUnicode(source -> pivot); 2354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * For pivoting conversion; and for direct conversion for 2356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * error callback handling, continuing partial matches 2357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and flushing the replay buffer. 2358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The pivot buffer is empty and reset. 2360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toUArgs.target=pivotStart; /* ==*pivotTarget */ 2362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* toUArgs.targetLimit=pivotLimit; already set before the loop */ 2363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _toUnicodeWithCallback(&toUArgs, pErrorCode); 2364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pivotTarget=toUArgs.target; 2365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 2366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* pivot overflow: continue with the conversion loop */ 2367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 2368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(U_FAILURE(*pErrorCode) || (!flush && *pivotTarget==pivotStart)) { 2369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* conversion error, or there was nothing left to convert */ 2370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 2371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * else: 2374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * _toUnicodeWithCallback() wrote into the pivot buffer, 2375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * continue with fromUnicode conversion. 2376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Set the fromUnicode flush flag if we flush and if toUnicode has 2378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * processed the end of the input. 2379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( flush && toUArgs.source==sourceLimit && 2381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceCnv->preToULength>=0 && 2382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceCnv->UCharErrorBufferLength==0 2383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fromUArgs.flush=TRUE; 2385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The conversion loop is exited when one of the following is true: 2390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * - the entire source text has been converted successfully to the target buffer 2391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * - a target buffer overflow occurred 2392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * - a conversion error occurred 2393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *source=toUArgs.source; 2396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *target=fromUArgs.target; 2397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* terminate the target buffer if possible */ 2399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(flush && U_SUCCESS(*pErrorCode)) { 2400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*target!=targetLimit) { 2401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru **target=0; 2402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_STRING_NOT_TERMINATED_WARNING) { 2403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 2404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_STRING_NOT_TERMINATED_WARNING; 2407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* internal implementation of ucnv_convert() etc. with preflighting */ 2412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 2413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_internalConvert(UConverter *outConverter, UConverter *inConverter, 2414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *target, int32_t targetCapacity, 2415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *source, int32_t sourceLength, 2416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 2417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar pivotBuffer[CHUNK_SIZE]; 2418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *pivot, *pivot2; 2419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *myTarget; 2421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *sourceLimit; 2422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *targetLimit; 2423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t targetLength=0; 2424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set up */ 2426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceLength<0) { 2427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLimit=uprv_strchr(source, 0); 2428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLimit=source+sourceLength; 2430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if there is no input data, we're done */ 2433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(source==sourceLimit) { 2434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, 0, pErrorCode); 2435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivot=pivot2=pivotBuffer; 2438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myTarget=target; 2439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLength=0; 2440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(targetCapacity>0) { 2442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* perform real conversion */ 2443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLimit=target+targetCapacity; 2444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_convertEx(outConverter, inConverter, 2445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &myTarget, targetLimit, 2446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &source, sourceLimit, 2447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotBuffer, &pivot, &pivot2, pivotBuffer+CHUNK_SIZE, 2448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FALSE, 2449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 2450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 2451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLength=(int32_t)(myTarget-target); 2452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If the output buffer is exhausted (or we are only "preflighting"), we need to stop writing 2456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to it but continue the conversion in order to store in targetCapacity 2457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the number of bytes that was required. 2458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || targetCapacity==0) 2460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char targetBuffer[CHUNK_SIZE]; 2462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLimit=targetBuffer+CHUNK_SIZE; 2464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 2465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 2466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myTarget=targetBuffer; 2467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_convertEx(outConverter, inConverter, 2468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &myTarget, targetLimit, 2469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &source, sourceLimit, 2470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pivotBuffer, &pivot, &pivot2, pivotBuffer+CHUNK_SIZE, 2471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FALSE, 2472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TRUE, 2473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 2474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLength+=(int32_t)(myTarget-targetBuffer); 2475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR); 2476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* done with preflighting, set warnings and errors as appropriate */ 2478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, targetLength, pErrorCode); 2479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no need to call u_terminateChars() because ucnv_convertEx() took care of that */ 2482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return targetLength; 2483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_convert(const char *toConverterName, const char *fromConverterName, 2487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *target, int32_t targetCapacity, 2488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *source, int32_t sourceLength, 2489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 2490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter in, out; /* stack-allocated */ 2491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *inConverter, *outConverter; 2492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t targetLength; 2493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 2495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( source==NULL || sourceLength<-1 || 2499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetCapacity<0 || (targetCapacity>0 && target==NULL) 2500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if there is no input data, we're done */ 2506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceLength==0 || (sourceLength<0 && *source==0)) { 2507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, 0, pErrorCode); 2508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* create the converters */ 2511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inConverter=ucnv_createConverter(&in, fromConverterName, pErrorCode); 2512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 2513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outConverter=ucnv_createConverter(&out, toConverterName, pErrorCode); 2517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 2518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(inConverter); 2519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLength=ucnv_internalConvert(outConverter, inConverter, 2523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru target, targetCapacity, 2524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, sourceLength, 2525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 2526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(inConverter); 2528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(outConverter); 2529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return targetLength; 2531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* @internal */ 2534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 2535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_convertAlgorithmic(UBool convertToAlgorithmic, 2536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterType algorithmicType, 2537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv, 2538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *target, int32_t targetCapacity, 2539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *source, int32_t sourceLength, 2540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 2541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter algoConverterStatic; /* stack-allocated */ 2542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *algoConverter, *to, *from; 2543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t targetLength; 2544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 2546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( cnv==NULL || source==NULL || sourceLength<-1 || 2550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetCapacity<0 || (targetCapacity>0 && target==NULL) 2551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 2552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 2553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if there is no input data, we're done */ 2557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceLength==0 || (sourceLength<0 && *source==0)) { 2558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, 0, pErrorCode); 2559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* create the algorithmic converter */ 2562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru algoConverter=ucnv_createAlgorithmicConverter(&algoConverterStatic, algorithmicType, 2563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "", 0, pErrorCode); 2564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 2565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset the other converter */ 2569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(convertToAlgorithmic) { 2570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* cnv->Unicode->algo */ 2571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_resetToUnicode(cnv); 2572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru to=algoConverter; 2573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru from=cnv; 2574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* algo->Unicode->cnv */ 2576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_resetFromUnicode(cnv); 2577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru from=algoConverter; 2578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru to=cnv; 2579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru targetLength=ucnv_internalConvert(to, from, 2582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru target, targetCapacity, 2583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, sourceLength, 2584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 2585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(algoConverter); 2587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return targetLength; 2589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_toAlgorithmic(UConverterType algorithmicType, 2593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv, 2594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *target, int32_t targetCapacity, 2595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *source, int32_t sourceLength, 2596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 2597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_convertAlgorithmic(TRUE, algorithmicType, cnv, 2598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru target, targetCapacity, 2599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, sourceLength, 2600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 2601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_fromAlgorithmic(UConverter *cnv, 2605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterType algorithmicType, 2606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *target, int32_t targetCapacity, 2607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *source, int32_t sourceLength, 2608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 2609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_convertAlgorithmic(FALSE, algorithmicType, cnv, 2610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru target, targetCapacity, 2611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, sourceLength, 2612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 2613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UConverterType U_EXPORT2 2616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getType(const UConverter* converter) 2617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t type = converter->sharedData->staticData->conversionType; 2619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 2620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(type == UCNV_MBCS) { 2621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_MBCSGetType(converter); 2622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 2624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UConverterType)type; 2625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 2628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getStarters(const UConverter* converter, 2629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool starters[256], 2630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode* err) 2631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (err == NULL || U_FAILURE(*err)) { 2633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(converter->sharedData->impl->getStarters != NULL) { 2637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->sharedData->impl->getStarters(converter, starters, err); 2638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 2640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UAmbiguousConverter *ucnv_getAmbiguous(const UConverter *cnv) 2644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode; 2646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name; 2647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i; 2648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv==NULL) { 2650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 2651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 2654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name=ucnv_getName(cnv, &errorCode); 2655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 2656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 2657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<(int32_t)(sizeof(ambiguousConverters)/sizeof(UAmbiguousConverter)); ++i) 2660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(0==uprv_strcmp(name, ambiguousConverters[i].name)) 2662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ambiguousConverters+i; 2664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 2668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 2671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_fixFileSeparator(const UConverter *cnv, 2672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* source, 2673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t sourceLength) { 2674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UAmbiguousConverter *a; 2675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i; 2676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar variant5c; 2677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv==NULL || source==NULL || sourceLength<=0 || (a=ucnv_getAmbiguous(cnv))==NULL) 2679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru variant5c=a->variant5c; 2684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<sourceLength; ++i) { 2685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(source[i]==variant5c) { 2686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source[i]=0x5c; 2687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 2692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_isAmbiguous(const UConverter *cnv) { 2693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UBool)(ucnv_getAmbiguous(cnv)!=NULL); 2694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 2697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setFallback(UConverter *cnv, UBool usesFallback) 2698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv->useFallback = usesFallback; 2700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 2703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_usesFallback(const UConverter *cnv) 2704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return cnv->useFallback; 2706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 2709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getInvalidChars (const UConverter * converter, 2710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *errBytes, 2711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t * len, 2712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 2713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (err == NULL || U_FAILURE(*err)) 2715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len == NULL || errBytes == NULL || converter == NULL) 2719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 2721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*len < converter->invalidCharLength) 2724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_INDEX_OUTOFBOUNDS_ERROR; 2726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((*len = converter->invalidCharLength) > 0) 2729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy (errBytes, converter->invalidCharBuffer, *len); 2731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 2735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getInvalidUChars (const UConverter * converter, 2736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *errChars, 2737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t * len, 2738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 2739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (err == NULL || U_FAILURE(*err)) 2741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len == NULL || errChars == NULL || converter == NULL) 2745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 2747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*len < converter->invalidUCharLength) 2750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_INDEX_OUTOFBOUNDS_ERROR; 2752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 2753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((*len = converter->invalidUCharLength) > 0) 2755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 2756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy (errChars, converter->invalidUCharBuffer, sizeof(UChar) * (*len)); 2757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SIG_MAX_LEN 5 2761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 2763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_detectUnicodeSignature( const char* source, 2764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t sourceLength, 2765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* signatureLength, 2766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode* pErrorCode) { 2767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t dummy; 2768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* initial 0xa5 bytes: make sure that if we read <SIG_MAX_LEN 2770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * bytes we don't misdetect something 2771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char start[SIG_MAX_LEN]={ '\xa5', '\xa5', '\xa5', '\xa5', '\xa5' }; 2773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int i = 0; 2774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((pErrorCode==NULL) || U_FAILURE(*pErrorCode)){ 2776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 2777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(source == NULL || sourceLength < -1){ 2780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 2781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 2782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(signatureLength == NULL) { 2785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru signatureLength = &dummy; 2786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sourceLength==-1){ 2789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLength=(int32_t)uprv_strlen(source); 2790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(i<sourceLength&& i<SIG_MAX_LEN){ 2794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start[i]=source[i]; 2795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i++; 2796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(start[0] == '\xFE' && start[1] == '\xFF') { 2799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=2; 2800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-16BE"; 2801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[0] == '\xFF' && start[1] == '\xFE') { 2802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(start[2] == '\x00' && start[3] =='\x00') { 2803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=4; 2804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-32LE"; 2805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 2806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=2; 2807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-16LE"; 2808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[0] == '\xEF' && start[1] == '\xBB' && start[2] == '\xBF') { 2810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=3; 2811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-8"; 2812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[0] == '\x00' && start[1] == '\x00' && 2813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start[2] == '\xFE' && start[3]=='\xFF') { 2814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=4; 2815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-32BE"; 2816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[0] == '\x0E' && start[1] == '\xFE' && start[2] == '\xFF') { 2817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=3; 2818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "SCSU"; 2819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[0] == '\xFB' && start[1] == '\xEE' && start[2] == '\x28') { 2820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=3; 2821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "BOCU-1"; 2822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[0] == '\x2B' && start[1] == '\x2F' && start[2] == '\x76') { 2823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 2824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * UTF-7: Initial U+FEFF is encoded as +/v8 or +/v9 or +/v+ or +/v/ 2825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * depending on the second UTF-16 code unit. 2826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Detect the entire, closed Unicode mode sequence +/v8- for only U+FEFF 2827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if it occurs. 2828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * So far we have +/v 2830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(start[3] == '\x38' && start[4] == '\x2D') { 2832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 5 bytes +/v8- */ 2833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=5; 2834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-7"; 2835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(start[3] == '\x38' || start[3] == '\x39' || start[3] == '\x2B' || start[3] == '\x2F') { 2836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 4 bytes +/v8 or +/v9 or +/v+ or +/v/ */ 2837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=4; 2838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-7"; 2839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else if(start[0]=='\xDD' && start[1]== '\x73'&& start[2]=='\x66' && start[3]=='\x73'){ 2841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=4; 2842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return "UTF-EBCDIC"; 2843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no known Unicode signature byte sequence recognized */ 2847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *signatureLength=0; 2848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 2849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_fromUCountPending(const UConverter* cnv, UErrorCode* status) 2853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 2854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)){ 2855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 2856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv == NULL){ 2858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 2859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 2860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 286254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(cnv->preFromUFirstCP >= 0){ 2863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return U16_LENGTH(cnv->preFromUFirstCP)+cnv->preFromULength ; 2864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else if(cnv->preFromULength < 0){ 2865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -cnv->preFromULength ; 2866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else if(cnv->fromUChar32 > 0){ 2867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 1; 2868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_toUCountPending(const UConverter* cnv, UErrorCode* status){ 2875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)){ 2877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 2878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv == NULL){ 2880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 2881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 2882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnv->preToULength > 0){ 2885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return cnv->preToULength ; 2886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else if(cnv->preToULength < 0){ 2887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -cnv->preToULength; 2888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else if(cnv->toULength > 0){ 2889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return cnv->toULength; 2890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 2891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 2892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 2893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 289454dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UBool U_EXPORT2 2895b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoucnv_isFixedWidth(UConverter *cnv, UErrorCode *status){ 2896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(*status)) { 2897b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 2898b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2899b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2900b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cnv == NULL) { 2901b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = U_ILLEGAL_ARGUMENT_ERROR; 2902b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 2903b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2904b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2905b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch (ucnv_getType(cnv)) { 2906b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UCNV_SBCS: 2907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UCNV_DBCS: 2908b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UCNV_UTF32_BigEndian: 2909b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UCNV_UTF32_LittleEndian: 2910b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UCNV_UTF32: 2911b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UCNV_US_ASCII: 2912b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 2913b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho default: 2914b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 2915b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2916b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 2918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Hey, Emacs, please set the following: 2921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Local Variables: 2923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * indent-tabs-mode: nil 2924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * End: 2925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 2927