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