16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1998-2013, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* ucnv.c: 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Implements APIs for the ICU's codeset conversion library; 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* mostly calls through internal functions; 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by Bertrand A. Damiba 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History: 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Date Name Description 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 04/04/99 helena Fixed internal header inclusion. 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 05/09/00 helena Added implementation to handle fallback mappings. 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 06/20/2000 helena OS/400 port changes; mostly typecast. 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_CONVERSION 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucnv.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucnv_err.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uset.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf16.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "putilimp.h" 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utracimp.h" 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ustr_imp.h" 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_imp.h" 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_cnv.h" 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucnv_bld.h" 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* size of intermediate and preflighting buffers in ucnv_convert() */ 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define CHUNK_SIZE 1024 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct UAmbiguousConverter { 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *name; 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar variant5c; 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} UAmbiguousConverter; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UAmbiguousConverter ambiguousConverters[]={ 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-897_P100-1995", 0xa5 }, 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-942_P120-1999", 0xa5 }, 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-943_P130-1999", 0xa5 }, 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-946_P100-1995", 0xa5 }, 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-33722_P120-1999", 0xa5 }, 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-1041_P100-1995", 0xa5 }, 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /*{ "ibm-54191_P100-2006", 0xa5 },*/ 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /*{ "ibm-62383_P100-2007", 0xa5 },*/ 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /*{ "ibm-891_P100-1995", 0x20a9 },*/ 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-944_P100-1995", 0x20a9 }, 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-949_P110-1999", 0x20a9 }, 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-1363_P110-1997", 0x20a9 }, 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ISO_2022,locale=ko,version=0", 0x20a9 }, 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "ibm-1088_P100-1995", 0x20a9 } 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*Calls through createConverter */ 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverter* U_EXPORT2 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_open (const char *name, 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *r; 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err == NULL || U_FAILURE (*err)) { 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r = ucnv_createConverter(NULL, name, err); 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return r; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverter* U_EXPORT2 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_openPackage (const char *packageName, const char *converterName, UErrorCode * err) 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_createConverterFromPackage(packageName, converterName, err); 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*Extracts the UChar* to a char* and calls through createConverter */ 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverter* U_EXPORT2 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_openU (const UChar * name, 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char asciiName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err == NULL || U_FAILURE(*err)) 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (name == NULL) 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_open (NULL, err); 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (u_strlen(name) >= UCNV_MAX_CONVERTER_NAME_LENGTH) 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_ILLEGAL_ARGUMENT_ERROR; 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_open(u_austrcpy(asciiName, name), err); 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Copy the string that is represented by the UConverterPlatform enum 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param platformString An output buffer 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param platform An enum representing a platform 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return the length of the copied string. 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_copyPlatformString(char *platformString, UConverterPlatform pltfrm) 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (pltfrm) 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_IBM: 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_strcpy(platformString, "ibm-"); 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 4; 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_UNKNOWN: 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* default to empty string */ 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *platformString = 0; 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*Assumes a $platform-#codepage.$CONVERTER_FILE_EXTENSION scheme and calls 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *through createConverter*/ 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverter* U_EXPORT2 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_openCCSID (int32_t codepage, 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterPlatform platform, 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char myName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t myNameLen; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err == NULL || U_FAILURE (*err)) 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* ucnv_copyPlatformString could return "ibm-" or "cp" */ 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org myNameLen = ucnv_copyPlatformString(myName, platform); 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org T_CString_integerToString(myName + myNameLen, codepage, 10); 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_createConverter(NULL, myName, err); 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Creating a temporary stack-based object that can be used in one thread, 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.organd created from a converter that is shared across threads. 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverter* U_EXPORT2 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status) 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *localConverter, *allocatedConverter; 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t stackBufferSize; 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t bufferSizeNeeded; 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *stackBufferChars = (char *)stackBuffer; 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode cbErr; 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs toUArgs = { 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(UConverterToUnicodeArgs), 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicodeArgs fromUArgs = { 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(UConverterFromUnicodeArgs), 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_ENTRY_OC(UTRACE_UCNV_CLONE); 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (status == NULL || U_FAILURE(*status)){ 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_STATUS(status? *status: U_ILLEGAL_ARGUMENT_ERROR); 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv == NULL) { 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_STATUS(*status); 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_DATA3(UTRACE_OPEN_CLOSE, "clone converter %s at %p into stackBuffer %p", 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_getName(cnv, status), cnv, stackBuffer); 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->sharedData->impl->safeClone != NULL) { 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* call the custom safeClone function for sizing */ 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bufferSizeNeeded = 0; 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->sharedData->impl->safeClone(cnv, NULL, &bufferSizeNeeded, status); 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(*status)) { 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_STATUS(*status); 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* inherent sizing */ 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bufferSizeNeeded = sizeof(UConverter); 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pBufferSize == NULL) { 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackBufferSize = 1; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBufferSize = &stackBufferSize; 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackBufferSize = *pBufferSize; 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (stackBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */ 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pBufferSize = bufferSizeNeeded; 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_VALUE(bufferSizeNeeded); 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Pointers on 64-bit platforms need to be aligned 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * on a 64-bit boundary in memory. 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) { 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars); 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(stackBufferSize > offsetUp) { 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackBufferSize -= offsetUp; 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackBufferChars += offsetUp; 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */ 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackBufferSize = 1; 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org stackBuffer = (void *)stackBufferChars; 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Now, see if we must allocate any memory */ 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (stackBufferSize < bufferSizeNeeded || stackBuffer == NULL) 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allocate one here...*/ 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter = allocatedConverter = (UConverter *) uprv_malloc (bufferSizeNeeded); 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(localConverter == NULL) { 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_STATUS(*status); 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_SAFECLONE_ALLOCATED_WARNING; 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* record the fact that memory was allocated */ 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pBufferSize = bufferSizeNeeded; 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* just use the stack buffer */ 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter = (UConverter*) stackBuffer; 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org allocatedConverter = NULL; 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(localConverter, 0, bufferSizeNeeded); 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Copy initial state */ 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(localConverter, cnv, sizeof(UConverter)); 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter->isCopyLocal = localConverter->isExtraLocal = FALSE; 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the substitution string */ 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->subChars == (uint8_t *)cnv->subUChars) { 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter->subChars = (uint8_t *)localConverter->subUChars; 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter->subChars = (uint8_t *)uprv_malloc(UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (localConverter->subChars == NULL) { 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(allocatedConverter); 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_STATUS(*status); 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(localConverter->subChars, cnv->subChars, UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* now either call the safeclone fcn or not */ 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->sharedData->impl->safeClone != NULL) { 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* call the custom safeClone function */ 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter = cnv->sharedData->impl->safeClone(cnv, localConverter, pBufferSize, status); 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(localConverter==NULL || U_FAILURE(*status)) { 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (allocatedConverter != NULL && allocatedConverter->subChars != (uint8_t *)allocatedConverter->subUChars) { 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(allocatedConverter->subChars); 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(allocatedConverter); 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_STATUS(*status); 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* increment refcount of shared data if needed */ 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Checking whether it's an algorithic converter is okay 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org in multithreaded applications because the value never changes. 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Don't check referenceCounter for any other value. 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->sharedData->referenceCounter != ~0) { 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_incrementRefCount(cnv->sharedData); 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(localConverter == (UConverter*)stackBuffer) { 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we're using user provided data - set to not destroy */ 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localConverter->isCopyLocal = TRUE; 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allow callback functions to handle any memory allocation */ 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.converter = fromUArgs.converter = localConverter; 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cbErr = U_ZERO_ERROR; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromCharErrorBehaviour(cnv->toUContext, &toUArgs, NULL, 0, UCNV_CLONE, &cbErr); 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cbErr = U_ZERO_ERROR; 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUCharErrorBehaviour(cnv->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLONE, &cbErr); 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT_PTR_STATUS(localConverter, *status); 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return localConverter; 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*Decreases the reference counter in the shared immutable section of the object 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *and frees the mutable part*/ 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_close (UConverter * converter) 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode errorCode = U_ZERO_ERROR; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_ENTRY_OC(UTRACE_UCNV_CLOSE); 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter == NULL) 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT(); 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_DATA3(UTRACE_OPEN_CLOSE, "close converter %s at %p, isCopyLocal=%b", 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_getName(converter, &errorCode), converter, converter->isCopyLocal); 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* In order to speed up the close, only call the callbacks when they have been changed. 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This performance check will only work when the callbacks are set within a shared library 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org or from user code that statically links this code. */ 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* first, notify the callback functions that the converter is closed */ 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->fromCharErrorBehaviour != UCNV_TO_U_DEFAULT_CALLBACK) { 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs toUArgs = { 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(UConverterToUnicodeArgs), 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.converter = converter; 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode = U_ZERO_ERROR; 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_CLOSE, &errorCode); 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->fromUCharErrorBehaviour != UCNV_FROM_U_DEFAULT_CALLBACK) { 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicodeArgs fromUArgs = { 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(UConverterFromUnicodeArgs), 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.converter = converter; 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode = U_ZERO_ERROR; 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLOSE, &errorCode); 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->sharedData->impl->close != NULL) { 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->sharedData->impl->close(converter); 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->subChars != (uint8_t *)converter->subUChars) { 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(converter->subChars); 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Checking whether it's an algorithic converter is okay 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org in multithreaded applications because the value never changes. 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Don't check referenceCounter for any other value. 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->sharedData->referenceCounter != ~0) { 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_unloadSharedDataIfReady(converter->sharedData); 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!converter->isCopyLocal){ 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(converter); 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRACE_EXIT(); 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*returns a single Name from the list, will return NULL if out of bounds 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const char* U_EXPORT2 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getAvailableName (int32_t n) 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (0 <= n && n <= 0xffff) { 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode err = U_ZERO_ERROR; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *name = ucnv_bld_getAvailableConverter((uint16_t)n, &err); 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(err)) { 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_countAvailable () 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode err = U_ZERO_ERROR; 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_bld_countAvailableConverters(&err); 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getSubstChars (const UConverter * converter, 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *mySubChar, 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int8_t * len, 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->subCharLen <= 0) { 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Unicode string or empty string from ucnv_setSubstString(). */ 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *len = 0; 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*len < converter->subCharLen) /*not enough space in subChars */ 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_INDEX_OUTOFBOUNDS_ERROR; 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy (mySubChar, converter->subChars, converter->subCharLen); /*fills in the subchars */ 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *len = converter->subCharLen; /*store # of bytes copied to buffer */ 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_setSubstChars (UConverter * converter, 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *mySubChar, 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int8_t len, 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /*Makes sure that the subChar is within the codepages char length boundaries */ 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((len > converter->sharedData->staticData->maxBytesPerChar) 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (len < converter->sharedData->staticData->minBytesPerChar)) 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_ILLEGAL_ARGUMENT_ERROR; 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy (converter->subChars, mySubChar, len); /*copies the subchars */ 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->subCharLen = len; /*sets the new len */ 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * There is currently (2001Feb) no separate API to set/get subChar1. 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In order to always have subChar written after it is explicitly set, 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * we set subChar1 to 0. 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->subChar1 = 0; 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_setSubstString(UConverter *cnv, 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s, 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length, 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *err) { 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UAlignedMemory cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE / sizeof(UAlignedMemory) + 1]; 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char chars[UCNV_ERROR_BUFFER_LENGTH]; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *clone; 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t *subChars; 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cloneSize, length8; 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Let the following functions check all arguments. */ 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cloneSize = sizeof(cloneBuffer); 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clone = ucnv_safeClone(cnv, cloneBuffer, &cloneSize, err); 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_setFromUCallBack(clone, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, err); 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length8 = ucnv_fromUChars(clone, chars, (int32_t)sizeof(chars), s, length, err); 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_close(clone); 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(*err)) { 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->sharedData->impl->writeSub == NULL 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_LEGACY_CONVERSION 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (cnv->sharedData->staticData->conversionType == UCNV_MBCS && 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_MBCSGetType(cnv) != UCNV_EBCDIC_STATEFUL) 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The converter is not stateful. Store the charset bytes as a fixed string. */ 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org subChars = (uint8_t *)chars; 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The converter has a non-default writeSub() function, indicating 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that it is stateful. 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Store the Unicode string for on-the-fly conversion for correct 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * state handling. 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length > UCNV_ERROR_BUFFER_LENGTH) { 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Should not occur. The converter should output at least one byte 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * per UChar, which means that ucnv_fromUChars() should catch all 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * overflows. 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_BUFFER_OVERFLOW_ERROR; 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org subChars = (uint8_t *)s; 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length < 0) { 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length = u_strlen(s); 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length8 = length * U_SIZEOF_UCHAR; 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For storing the substitution string, select either the small buffer inside 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * UConverter or allocate a subChars buffer. 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length8 > UCNV_MAX_SUBCHAR_LEN) { 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Use a separate buffer for the string. Outside UConverter to not make it too large. */ 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->subChars == (uint8_t *)cnv->subUChars) { 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Allocate a new buffer for the string. */ 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->subChars = (uint8_t *)uprv_malloc(UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv->subChars == NULL) { 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->subChars = (uint8_t *)cnv->subUChars; 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_MEMORY_ALLOCATION_ERROR; 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(cnv->subChars, 0, UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR); 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Copy the substitution string into the UConverter or its subChars buffer. */ 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length8 == 0) { 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->subCharLen = 0; 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(cnv->subChars, subChars, length8); 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (subChars == (uint8_t *)chars) { 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->subCharLen = (int8_t)length8; 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* subChars == s */ { 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->subCharLen = (int8_t)-length; 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* See comment in ucnv_setSubstChars(). */ 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->subChar1 = 0; 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*resets the internal states of a converter 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *goal : have the same behaviour than a freshly created converter 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void _reset(UConverter *converter, UConverterResetChoice choice, 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool callCallback) { 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(converter == NULL) { 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(callCallback) { 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* first, notify the callback functions that the converter is reset */ 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode errorCode; 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(choice<=UCNV_RESET_TO_UNICODE && converter->fromCharErrorBehaviour != UCNV_TO_U_DEFAULT_CALLBACK) { 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs toUArgs = { 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(UConverterToUnicodeArgs), 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.converter = converter; 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode = U_ZERO_ERROR; 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode); 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(choice!=UCNV_RESET_TO_UNICODE && converter->fromUCharErrorBehaviour != UCNV_FROM_U_DEFAULT_CALLBACK) { 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicodeArgs fromUArgs = { 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sizeof(UConverterFromUnicodeArgs), 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.converter = converter; 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode = U_ZERO_ERROR; 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode); 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* now reset the converter itself */ 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(choice<=UCNV_RESET_TO_UNICODE) { 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus; 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->mode = 0; 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->toULength = 0; 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->invalidCharLength = converter->UCharErrorBufferLength = 0; 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->preToULength = 0; 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(choice!=UCNV_RESET_TO_UNICODE) { 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromUnicodeStatus = 0; 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromUChar32 = 0; 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->invalidUCharLength = converter->charErrorBufferLength = 0; 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->preFromUFirstCP = U_SENTINEL; 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->preFromULength = 0; 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (converter->sharedData->impl->reset != NULL) { 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* call the custom reset function */ 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->sharedData->impl->reset(converter, choice); 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_reset(UConverter *converter) 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(converter, UCNV_RESET_BOTH, TRUE); 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_resetToUnicode(UConverter *converter) 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(converter, UCNV_RESET_TO_UNICODE, TRUE); 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_resetFromUnicode(UConverter *converter) 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(converter, UCNV_RESET_FROM_UNICODE, TRUE); 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int8_t U_EXPORT2 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getMaxCharSize (const UConverter * converter) 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return converter->maxBytesPerUChar; 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int8_t U_EXPORT2 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getMinCharSize (const UConverter * converter) 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return converter->sharedData->staticData->minBytesPerChar; 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const char* U_EXPORT2 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getName (const UConverter * converter, UErrorCode * err) 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(converter->sharedData->impl->getName){ 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char* temp= converter->sharedData->impl->getName(converter); 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(temp) 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return temp; 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return converter->sharedData->staticData->name; 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getCCSID(const UConverter * converter, 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t ccsid; 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ccsid = converter->sharedData->staticData->codepage; 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ccsid == 0) { 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Rare case. This is for cases like gb18030, 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org which doesn't have an IBM canonical name, but does have an IBM alias. */ 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *standardName = ucnv_getStandardName(ucnv_getName(converter, err), "IBM", err); 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(*err) && standardName) { 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *ccsidStr = uprv_strchr(standardName, '-'); 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ccsidStr) { 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ccsid = (int32_t)atol(ccsidStr+1); /* +1 to skip '-' */ 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ccsid; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverterPlatform U_EXPORT2 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getPlatform (const UConverter * converter, 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UCNV_UNKNOWN; 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UConverterPlatform)converter->sharedData->staticData->platform; 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_getToUCallBack (const UConverter * converter, 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUCallback *action, 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void **context) 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *action = converter->fromCharErrorBehaviour; 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *context = converter->toUContext; 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_getFromUCallBack (const UConverter * converter, 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUCallback *action, 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void **context) 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *action = converter->fromUCharErrorBehaviour; 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *context = converter->fromUContext; 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_setToUCallBack (UConverter * converter, 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUCallback newAction, 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void* newContext, 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUCallback *oldAction, 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void** oldContext, 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (oldAction) *oldAction = converter->fromCharErrorBehaviour; 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromCharErrorBehaviour = newAction; 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (oldContext) *oldContext = converter->toUContext; 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->toUContext = newContext; 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_setFromUCallBack (UConverter * converter, 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUCallback newAction, 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void* newContext, 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUCallback *oldAction, 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void** oldContext, 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE (*err)) 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (oldAction) *oldAction = converter->fromUCharErrorBehaviour; 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromUCharErrorBehaviour = newAction; 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (oldContext) *oldContext = converter->fromUContext; 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->fromUContext = newContext; 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_updateOffsets(int32_t *offsets, int32_t length, 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sourceIndex, int32_t errorInputLength) { 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *limit; 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t delta, offset; 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceIndex>=0) { 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * adjust each offset by adding the previous sourceIndex 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * minus the length of the input sequence that caused an 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * error, if any 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delta=sourceIndex-errorInputLength; 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set each offset to -1 because this conversion function 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * does not handle offsets 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delta=-1; 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=offsets+length; 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(delta==0) { 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* most common case, nothing to do */ 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(delta>0) { 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* add the delta to each offset (but not if the offset is <0) */ 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(offsets<limit) { 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offset=*offsets; 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offset>=0) { 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *offsets=offset+delta; 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++offsets; 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else /* delta<0 */ { 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set each offset to -1 because this conversion function 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * does not handle offsets 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or the error input sequence started in a previous buffer 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(offsets<limit) { 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *offsets++=-1; 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ucnv_fromUnicode --------------------------------------------------------- */ 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Implementation note for m:n conversions 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * While collecting source units to find the longest match for m:n conversion, 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * some source units may need to be stored for a partial match. 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * When a second buffer does not yield a match on all of the previously stored 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * source units, then they must be "replayed", i.e., fed back into the converter. 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The code relies on the fact that replaying will not nest - 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * converting a replay buffer will not result in a replay. 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is because a replay is necessary only after the _continuation_ of a 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * partial match failed, but a replay buffer is converted as a whole. 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * It may result in some of its units being stored again for a partial match, 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * but there will not be a continuation _during_ the replay which could fail. 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * It is conceivable that a callback function could call the converter 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * recursively in a way that causes another replay to be stored, but that 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * would be an error in the callback function. 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Such violations will cause assertion failures in a debug build, 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and wrong output, but they will not cause a crash. 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) { 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicode fromUnicode; 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *cnv; 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s; 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *t; 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *offsets; 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sourceIndex; 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t errorInputLength; 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool converterSawEndOfInput, calledCallback; 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* variables for m:n conversion */ 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar replay[UCNV_EXT_MAX_UCHARS]; 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *realSource, *realSourceLimit; 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t realSourceIndex; 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool realFlush; 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv=pArgs->converter; 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=pArgs->source; 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=pArgs->target; 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets=pArgs->offsets; 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get the converter implementation function */ 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=0; 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets==NULL) { 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUnicode=cnv->sharedData->impl->fromUnicode; 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUnicode=cnv->sharedData->impl->fromUnicodeWithOffsets; 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(fromUnicode==NULL) { 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* there is no WithOffsets implementation */ 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUnicode=cnv->sharedData->impl->fromUnicode; 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we will write -1 for each offset */ 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=-1; 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->preFromULength>=0) { 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* normal mode */ 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=NULL; 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* avoid compiler warnings - not otherwise necessary, and the values do not matter */ 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceLimit=NULL; 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realFlush=FALSE; 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceIndex=0; 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Previous m:n conversion stored source units from a partial match 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and failed to consume all of them. 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to "replay" them from a temporary buffer and convert them first. 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=pArgs->source; 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceLimit=pArgs->sourceLimit; 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realFlush=pArgs->flush; 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceIndex=sourceIndex; 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(replay, cnv->preFromU, -cnv->preFromULength*U_SIZEOF_UCHAR); 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=replay; 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=replay-cnv->preFromULength; 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=FALSE; 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=-1; 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=0; 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop for conversion and error handling 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop { 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * convert 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop { 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * update offsets 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * handle end of input 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * handle errors/call callback 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(*err)) { 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* convert */ 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUnicode(pArgs, err); 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set a flag for whether the converter 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * successfully processed the end of the input 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * need not check cnv->preFromULength==0 because a replay (<0) will cause 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * s<sourceLimit before converterSawEndOfInput is checked 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converterSawEndOfInput= 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (UBool)(U_SUCCESS(*err) && 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush && pArgs->source==pArgs->sourceLimit && 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUChar32==0); 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* handle error from ucnv_convertEx() */ 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converterSawEndOfInput=FALSE; 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no callback called yet for this iteration */ 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calledCallback=FALSE; 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no sourceIndex adjustment for conversion, only for callback output */ 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorInputLength=0; 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop for offsets and error handling 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * iterates at most 3 times: 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1. to clean up after the conversion function 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2. after the callback 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3. after the callback again if there was truncated input 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* update offsets if we write any */ 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=(int32_t)(pArgs->target-t); 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>0) { 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _updateOffsets(offsets, length, sourceIndex, errorInputLength); 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if a converter handles offsets and updates the offsets 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * pointer at the end, then pArgs->offset should not change 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * here; 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * however, some converters do not handle offsets at all 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (sourceIndex<0) or may not update the offsets pointer 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->offsets=offsets+=length; 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceIndex>=0) { 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex+=(int32_t)(pArgs->source-s); 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->preFromULength<0) { 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * switch the source to new replay units (cannot occur while replaying) 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after offset handling and before end-of-input and callback handling 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(realSource==NULL) { 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=pArgs->source; 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceLimit=pArgs->sourceLimit; 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realFlush=pArgs->flush; 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceIndex=sourceIndex; 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(replay, cnv->preFromU, -cnv->preFromULength*U_SIZEOF_UCHAR); 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=replay; 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=replay-cnv->preFromULength; 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=FALSE; 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((sourceIndex+=cnv->preFromULength)<0) { 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=-1; 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=0; 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* see implementation note before _fromUnicodeWithCallback() */ 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(realSource==NULL); 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_INTERNAL_PROGRAM_ERROR; 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* update pointers */ 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=pArgs->source; 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=pArgs->target; 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(*err)) { 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(s<pArgs->sourceLimit) { 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * continue with the conversion loop while there is still input left 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (continue converting by breaking out of only the inner loop) 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(realSource!=NULL) { 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* switch back from replaying to the real source and continue */ 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=realSource; 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=realSourceLimit; 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=realFlush; 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=realSourceIndex; 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=NULL; 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(pArgs->flush && cnv->fromUChar32!=0) { 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the entire input stream is consumed 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and there is a partial, truncated input sequence left 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* inject an error and continue with callback handling */ 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_TRUNCATED_CHAR_FOUND; 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calledCallback=FALSE; /* new error condition */ 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* input consumed */ 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pArgs->flush) { 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * return to the conversion loop once more if the flush 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * flag is set and the conversion function has not 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * successfully processed the end of the input yet 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (continue converting by breaking out of only the inner loop) 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!converterSawEndOfInput) { 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the converter without calling the callback function */ 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(cnv, UCNV_RESET_FROM_UNICODE, FALSE); 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* done successfully */ 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* U_FAILURE(*err) */ 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode e; 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( calledCallback || 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (e=*err)==U_BUFFER_OVERFLOW_ERROR || 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (e!=U_INVALID_CHAR_FOUND && 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org e!=U_ILLEGAL_CHAR_FOUND && 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org e!=U_TRUNCATED_CHAR_FOUND) 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the callback did not or cannot resolve the error: 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set output pointers and return 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the check for buffer overflow is redundant but it is 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a high-runner case and hopefully documents the intent 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * well 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if we were replaying, then the replay buffer must be 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * copied back into the UConverter 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and the real arguments must be restored 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(realSource!=NULL) { 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(cnv->preFromULength==0); 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=(int32_t)(pArgs->sourceLimit-pArgs->source); 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>0) { 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(cnv->preFromU, pArgs->source, length*U_SIZEOF_UCHAR); 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preFromULength=(int8_t)-length; 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=realSource; 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=realSourceLimit; 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=realFlush; 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* callback handling */ 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 codePoint; 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get and write the code point */ 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org codePoint=cnv->fromUChar32; 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorInputLength=0; 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_APPEND_UNSAFE(cnv->invalidUCharBuffer, errorInputLength, codePoint); 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->invalidUCharLength=(int8_t)errorInputLength; 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the converter state to deal with the next character */ 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUChar32=0; 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* call the callback function */ 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromUCharErrorBehaviour(cnv->fromUContext, pArgs, 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->invalidUCharBuffer, errorInputLength, codePoint, 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err==U_INVALID_CHAR_FOUND ? UCNV_UNASSIGNED : UCNV_ILLEGAL, 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org err); 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop back to the offset handling 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * this flag will indicate after offset handling 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that a callback was called; 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if the callback did not resolve the error, then we return 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calledCallback=TRUE; 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Output the fromUnicode overflow buffer. 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Call this function if(cnv->charErrorBufferLength>0). 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return TRUE if overflow 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_outputOverflowFromUnicode(UConverter *cnv, 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char **target, const char *targetLimit, 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t **pOffsets, 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *err) { 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *offsets; 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *overflow, *t; 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, length; 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=*target; 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pOffsets!=NULL) { 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets=*pOffsets; 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets=NULL; 11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflow=(char *)cnv->charErrorBuffer; 11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=cnv->charErrorBufferLength; 11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=0; 11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(i<length) { 11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(t==targetLimit) { 11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the overflow buffer contains too much, keep the rest */ 11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j=0; 11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 11496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflow[j++]=overflow[i++]; 11506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(i<length); 11516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->charErrorBufferLength=(int8_t)j; 11536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=t; 11546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 11556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pOffsets=offsets; 11566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_BUFFER_OVERFLOW_ERROR; 11586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 11596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the overflow contents to the target */ 11626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *t++=overflow[i++]; 11636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 11646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *offsets++=-1; /* no source index available for old output */ 11656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the overflow buffer is completely copied to the target */ 11696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->charErrorBufferLength=0; 11706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=t; 11716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 11726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pOffsets=offsets; 11736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 11756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 11786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_fromUnicode(UConverter *cnv, 11796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char **target, const char *targetLimit, 11806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar **source, const UChar *sourceLimit, 11816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *offsets, 11826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool flush, 11836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *err) { 11846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicodeArgs args; 11856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s; 11866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *t; 11876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check parameters */ 11896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(err==NULL || U_FAILURE(*err)) { 11906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv==NULL || target==NULL || source==NULL) { 11946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 11956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=*source; 11996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=*target; 12006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((const void *)U_MAX_PTR(sourceLimit) == (const void *)sourceLimit) { 12026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 12036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Prevent code from going into an infinite loop in case we do hit this 12046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit. The limit pointer is expected to be on a UChar * boundary. 12056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This also prevents the next argument check from failing. 12066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceLimit = (const UChar *)(((const char *)sourceLimit) - 1); 12086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 12116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * All these conditions should never happen. 12126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1) Make sure that the limits are >= to the address source or target 12146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2) Make sure that the buffer sizes do not exceed the number range for 12166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * int32_t because some functions use the size (in units or bytes) 12176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * rather than comparing pointers, and because offsets are int32_t values. 12186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * size_t is guaranteed to be unsigned and large enough for the job. 12206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return with an error instead of adjusting the limits because we would 12226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * not be able to maintain the semantics that either the source must be 12236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * consumed or the target filled (unless an error occurs). 12246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * An adjustment would be targetLimit=t+0x7fffffff; for example. 12256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3) Make sure that the user didn't incorrectly cast a UChar * pointer 12276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to a char * pointer and provide an incomplete UChar code unit. 12286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sourceLimit<s || targetLimit<t || 12306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((size_t)(sourceLimit-s)>(size_t)0x3fffffff && sourceLimit>s) || 12316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) || 12326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (((const char *)sourceLimit-(const char *)s) & 1) != 0) 12336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 12346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 12356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 12366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output the target overflow buffer */ 12396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( cnv->charErrorBufferLength>0 && 12406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_outputOverflowFromUnicode(cnv, target, targetLimit, &offsets, err) 12416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 12426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* U_BUFFER_OVERFLOW_ERROR */ 12436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 12446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* *target may have moved, therefore stop using t */ 12466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!flush && s==sourceLimit && cnv->preFromULength>=0) { 12486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the overflow buffer is emptied and there is no new input: we are done */ 12496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 12506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 12536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Do not simply return with a buffer overflow error if 12546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * !flush && t==targetLimit 12556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * because it is possible that the source will not generate any output. 12566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For example, the skip callback may be called; 12576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * it does not output anything. 12586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* prepare the converter arguments */ 12616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.converter=cnv; 12626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.flush=flush; 12636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.offsets=offsets; 12646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.source=s; 12656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.sourceLimit=sourceLimit; 12666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.target=*target; 12676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.targetLimit=targetLimit; 12686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.size=sizeof(args); 12696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _fromUnicodeWithCallback(&args, err); 12716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *source=args.source; 12736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=args.target; 12746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ucnv_toUnicode() --------------------------------------------------------- */ 12776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 12796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_toUnicodeWithCallback(UConverterToUnicodeArgs *pArgs, UErrorCode *err) { 12806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicode toUnicode; 12816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *cnv; 12826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *s; 12836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *t; 12846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *offsets; 12856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sourceIndex; 12866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t errorInputLength; 12876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool converterSawEndOfInput, calledCallback; 12886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* variables for m:n conversion */ 12906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char replay[UCNV_EXT_MAX_BYTES]; 12916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *realSource, *realSourceLimit; 12926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t realSourceIndex; 12936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool realFlush; 12946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv=pArgs->converter; 12966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=pArgs->source; 12976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=pArgs->target; 12986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets=pArgs->offsets; 12996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get the converter implementation function */ 13016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=0; 13026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets==NULL) { 13036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUnicode=cnv->sharedData->impl->toUnicode; 13046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 13056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUnicode=cnv->sharedData->impl->toUnicodeWithOffsets; 13066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(toUnicode==NULL) { 13076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* there is no WithOffsets implementation */ 13086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUnicode=cnv->sharedData->impl->toUnicode; 13096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we will write -1 for each offset */ 13106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=-1; 13116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->preToULength>=0) { 13156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* normal mode */ 13166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=NULL; 13176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* avoid compiler warnings - not otherwise necessary, and the values do not matter */ 13196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceLimit=NULL; 13206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realFlush=FALSE; 13216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceIndex=0; 13226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 13236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 13246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Previous m:n conversion stored source units from a partial match 13256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and failed to consume all of them. 13266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to "replay" them from a temporary buffer and convert them first. 13276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 13286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=pArgs->source; 13296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceLimit=pArgs->sourceLimit; 13306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realFlush=pArgs->flush; 13316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceIndex=sourceIndex; 13326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(replay, cnv->preToU, -cnv->preToULength); 13346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=replay; 13356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=replay-cnv->preToULength; 13366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=FALSE; 13376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=-1; 13386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=0; 13406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 13436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop for conversion and error handling 13446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 13456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop { 13466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * convert 13476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop { 13486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * update offsets 13496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * handle end of input 13506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * handle errors/call callback 13516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 13526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 13536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 13546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 13556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(*err)) { 13566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* convert */ 13576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUnicode(pArgs, err); 13586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 13606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set a flag for whether the converter 13616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * successfully processed the end of the input 13626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 13636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * need not check cnv->preToULength==0 because a replay (<0) will cause 13646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * s<sourceLimit before converterSawEndOfInput is checked 13656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 13666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converterSawEndOfInput= 13676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (UBool)(U_SUCCESS(*err) && 13686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush && pArgs->source==pArgs->sourceLimit && 13696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->toULength==0); 13706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 13716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* handle error from getNextUChar() or ucnv_convertEx() */ 13726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converterSawEndOfInput=FALSE; 13736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no callback called yet for this iteration */ 13766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calledCallback=FALSE; 13776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no sourceIndex adjustment for conversion, only for callback output */ 13796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorInputLength=0; 13806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 13826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop for offsets and error handling 13836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 13846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * iterates at most 3 times: 13856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1. to clean up after the conversion function 13866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2. after the callback 13876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3. after the callback again if there was truncated input 13886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 13896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 13906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* update offsets if we write any */ 13916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 13926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=(int32_t)(pArgs->target-t); 13936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>0) { 13946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _updateOffsets(offsets, length, sourceIndex, errorInputLength); 13956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 13976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if a converter handles offsets and updates the offsets 13986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * pointer at the end, then pArgs->offset should not change 13996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * here; 14006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * however, some converters do not handle offsets at all 14016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (sourceIndex<0) or may not update the offsets pointer 14026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->offsets=offsets+=length; 14046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceIndex>=0) { 14076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex+=(int32_t)(pArgs->source-s); 14086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->preToULength<0) { 14126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 14136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * switch the source to new replay units (cannot occur while replaying) 14146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after offset handling and before end-of-input and callback handling 14156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(realSource==NULL) { 14176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=pArgs->source; 14186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceLimit=pArgs->sourceLimit; 14196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realFlush=pArgs->flush; 14206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSourceIndex=sourceIndex; 14216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(replay, cnv->preToU, -cnv->preToULength); 14236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=replay; 14246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=replay-cnv->preToULength; 14256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=FALSE; 14266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((sourceIndex+=cnv->preToULength)<0) { 14276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=-1; 14286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=0; 14316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 14326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* see implementation note before _fromUnicodeWithCallback() */ 14336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(realSource==NULL); 14346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_INTERNAL_PROGRAM_ERROR; 14356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* update pointers */ 14396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=pArgs->source; 14406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=pArgs->target; 14416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(*err)) { 14436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(s<pArgs->sourceLimit) { 14446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 14456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * continue with the conversion loop while there is still input left 14466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (continue converting by breaking out of only the inner loop) 14476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 14496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(realSource!=NULL) { 14506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* switch back from replaying to the real source and continue */ 14516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=realSource; 14526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=realSourceLimit; 14536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=realFlush; 14546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceIndex=realSourceIndex; 14556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org realSource=NULL; 14576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 14586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(pArgs->flush && cnv->toULength>0) { 14596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 14606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the entire input stream is consumed 14616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and there is a partial, truncated input sequence left 14626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* inject an error and continue with callback handling */ 14656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_TRUNCATED_CHAR_FOUND; 14666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calledCallback=FALSE; /* new error condition */ 14676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 14686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* input consumed */ 14696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pArgs->flush) { 14706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 14716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * return to the conversion loop once more if the flush 14726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * flag is set and the conversion function has not 14736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * successfully processed the end of the input yet 14746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 14756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (continue converting by breaking out of only the inner loop) 14766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!converterSawEndOfInput) { 14786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 14796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the converter without calling the callback function */ 14826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(cnv, UCNV_RESET_TO_UNICODE, FALSE); 14836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* done successfully */ 14866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 14876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* U_FAILURE(*err) */ 14916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 14926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode e; 14936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( calledCallback || 14956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (e=*err)==U_BUFFER_OVERFLOW_ERROR || 14966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (e!=U_INVALID_CHAR_FOUND && 14976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org e!=U_ILLEGAL_CHAR_FOUND && 14986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org e!=U_TRUNCATED_CHAR_FOUND && 14996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org e!=U_ILLEGAL_ESCAPE_SEQUENCE && 15006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org e!=U_UNSUPPORTED_ESCAPE_SEQUENCE) 15016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 15026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 15036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the callback did not or cannot resolve the error: 15046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set output pointers and return 15056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 15066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the check for buffer overflow is redundant but it is 15076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a high-runner case and hopefully documents the intent 15086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * well 15096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 15106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if we were replaying, then the replay buffer must be 15116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * copied back into the UConverter 15126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and the real arguments must be restored 15136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 15146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(realSource!=NULL) { 15156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 15166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(cnv->preToULength==0); 15186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=(int32_t)(pArgs->sourceLimit-pArgs->source); 15206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>0) { 15216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(cnv->preToU, pArgs->source, length); 15226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->preToULength=(int8_t)-length; 15236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->source=realSource; 15266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->sourceLimit=realSourceLimit; 15276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pArgs->flush=realFlush; 15286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 15316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy toUBytes[] to invalidCharBuffer[] */ 15356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorInputLength=cnv->invalidCharLength=cnv->toULength; 15366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(errorInputLength>0) { 15376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(cnv->invalidCharBuffer, cnv->toUBytes, errorInputLength); 15386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the converter state to deal with the next character */ 15416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->toULength=0; 15426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* call the callback function */ 15446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->toUCallbackReason==UCNV_ILLEGAL && *err==U_INVALID_CHAR_FOUND) { 15456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->toUCallbackReason = UCNV_UNASSIGNED; 15466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->fromCharErrorBehaviour(cnv->toUContext, pArgs, 15486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->invalidCharBuffer, errorInputLength, 15496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->toUCallbackReason, 15506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org err); 15516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->toUCallbackReason = UCNV_ILLEGAL; /* reset to default value */ 15526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 15546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * loop back to the offset handling 15556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 15566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * this flag will indicate after offset handling 15576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that a callback was called; 15586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if the callback did not resolve the error, then we return 15596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 15606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calledCallback=TRUE; 15616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 15646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 15666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Output the toUnicode overflow buffer. 15676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Call this function if(cnv->UCharErrorBufferLength>0). 15686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return TRUE if overflow 15696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 15706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool 15716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_outputOverflowToUnicode(UConverter *cnv, 15726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar **target, const UChar *targetLimit, 15736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t **pOffsets, 15746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *err) { 15756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *offsets; 15766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *overflow, *t; 15776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, length; 15786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=*target; 15806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pOffsets!=NULL) { 15816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets=*pOffsets; 15826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 15836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets=NULL; 15846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflow=cnv->UCharErrorBuffer; 15876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=cnv->UCharErrorBufferLength; 15886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=0; 15896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(i<length) { 15906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(t==targetLimit) { 15916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the overflow buffer contains too much, keep the rest */ 15926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j=0; 15936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 15956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflow[j++]=overflow[i++]; 15966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(i<length); 15976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBufferLength=(int8_t)j; 15996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=t; 16006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 16016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pOffsets=offsets; 16026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_BUFFER_OVERFLOW_ERROR; 16046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 16056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the overflow contents to the target */ 16086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *t++=overflow[i++]; 16096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 16106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *offsets++=-1; /* no source index available for old output */ 16116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the overflow buffer is completely copied to the target */ 16156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBufferLength=0; 16166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=t; 16176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offsets!=NULL) { 16186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pOffsets=offsets; 16196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 16216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 16226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 16246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_toUnicode(UConverter *cnv, 16256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar **target, const UChar *targetLimit, 16266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char **source, const char *sourceLimit, 16276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *offsets, 16286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool flush, 16296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *err) { 16306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs args; 16316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *s; 16326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *t; 16336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check parameters */ 16356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(err==NULL || U_FAILURE(*err)) { 16366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 16376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv==NULL || target==NULL || source==NULL) { 16406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 16416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 16426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=*source; 16456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=*target; 16466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((const void *)U_MAX_PTR(targetLimit) == (const void *)targetLimit) { 16486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 16496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Prevent code from going into an infinite loop in case we do hit this 16506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit. The limit pointer is expected to be on a UChar * boundary. 16516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This also prevents the next argument check from failing. 16526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 16536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLimit = (const UChar *)(((const char *)targetLimit) - 1); 16546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 16576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * All these conditions should never happen. 16586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 16596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1) Make sure that the limits are >= to the address source or target 16606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 16616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2) Make sure that the buffer sizes do not exceed the number range for 16626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * int32_t because some functions use the size (in units or bytes) 16636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * rather than comparing pointers, and because offsets are int32_t values. 16646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 16656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * size_t is guaranteed to be unsigned and large enough for the job. 16666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 16676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return with an error instead of adjusting the limits because we would 16686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * not be able to maintain the semantics that either the source must be 16696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * consumed or the target filled (unless an error occurs). 16706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * An adjustment would be sourceLimit=t+0x7fffffff; for example. 16716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 16726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3) Make sure that the user didn't incorrectly cast a UChar * pointer 16736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to a char * pointer and provide an incomplete UChar code unit. 16746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 16756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sourceLimit<s || targetLimit<t || 16766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s) || 16776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((size_t)(targetLimit-t)>(size_t)0x3fffffff && targetLimit>t) || 16786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (((const char *)targetLimit-(const char *)t) & 1) != 0 16796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 16806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 16816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 16826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output the target overflow buffer */ 16856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( cnv->UCharErrorBufferLength>0 && 16866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_outputOverflowToUnicode(cnv, target, targetLimit, &offsets, err) 16876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 16886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* U_BUFFER_OVERFLOW_ERROR */ 16896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 16906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* *target may have moved, therefore stop using t */ 16926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!flush && s==sourceLimit && cnv->preToULength>=0) { 16946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the overflow buffer is emptied and there is no new input: we are done */ 16956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 16966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 16996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Do not simply return with a buffer overflow error if 17006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * !flush && t==targetLimit 17016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * because it is possible that the source will not generate any output. 17026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For example, the skip callback may be called; 17036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * it does not output anything. 17046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 17056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* prepare the converter arguments */ 17076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.converter=cnv; 17086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.flush=flush; 17096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.offsets=offsets; 17106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.source=s; 17116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.sourceLimit=sourceLimit; 17126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.target=*target; 17136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.targetLimit=targetLimit; 17146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.size=sizeof(args); 17156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _toUnicodeWithCallback(&args, err); 17176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *source=args.source; 17196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=args.target; 17206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 17216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ucnv_to/fromUChars() ----------------------------------------------------- */ 17236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 17256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_fromUChars(UConverter *cnv, 17266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *dest, int32_t destCapacity, 17276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *src, int32_t srcLength, 17286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 17296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *srcLimit; 17306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *originalDest, *destLimit; 17316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t destLength; 17326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check arguments */ 17346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 17356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 17366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( cnv==NULL || 17396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destCapacity<0 || (destCapacity>0 && dest==NULL) || 17406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength<-1 || (srcLength!=0 && src==NULL) 17416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 17426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 17436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 17446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize */ 17476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_resetFromUnicode(cnv); 17486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org originalDest=dest; 17496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength==-1) { 17506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength=u_strlen(src); 17516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength>0) { 17536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLimit=src+srcLength; 17546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLimit=dest+destCapacity; 17556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */ 17576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(destLimit<dest || (destLimit==NULL && dest!=NULL)) { 17586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLimit=(char *)U_MAX_PTR(dest); 17596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* perform the conversion */ 17626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 17636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLength=(int32_t)(dest-originalDest); 17646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if an overflow occurs, then get the preflighting length */ 17666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 17676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char buffer[1024]; 17686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLimit=buffer+sizeof(buffer); 17706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 17716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest=buffer; 17726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 17736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 17746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLength+=(int32_t)(dest-buffer); 17756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR); 17766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 17786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLength=0; 17796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateChars(originalDest, destCapacity, destLength, pErrorCode); 17826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 17836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 17856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_toUChars(UConverter *cnv, 17866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *dest, int32_t destCapacity, 17876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *src, int32_t srcLength, 17886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 17896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *srcLimit; 17906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *originalDest, *destLimit; 17916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t destLength; 17926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check arguments */ 17946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 17956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 17966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( cnv==NULL || 17996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destCapacity<0 || (destCapacity>0 && dest==NULL) || 18006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength<-1 || (srcLength!=0 && src==NULL)) 18016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 18036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 18046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize */ 18076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_resetToUnicode(cnv); 18086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org originalDest=dest; 18096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength==-1) { 18106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength=(int32_t)uprv_strlen(src); 18116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength>0) { 18136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLimit=src+srcLength; 18146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLimit=dest+destCapacity; 18156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */ 18176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(destLimit<dest || (destLimit==NULL && dest!=NULL)) { 18186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLimit=(UChar *)U_MAX_PTR(dest); 18196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* perform the conversion */ 18226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 18236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLength=(int32_t)(dest-originalDest); 18246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if an overflow occurs, then get the preflighting length */ 18266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) 18276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 18286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar buffer[1024]; 18296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLimit=buffer+sizeof(buffer)/U_SIZEOF_UCHAR; 18316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 18326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest=buffer; 18336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 18346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode); 18356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLength+=(int32_t)(dest-buffer); 18366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR); 18386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 18406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org destLength=0; 18416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateUChars(originalDest, destCapacity, destLength, pErrorCode); 18446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ucnv_getNextUChar() ------------------------------------------------------ */ 18476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UChar32 U_EXPORT2 18496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getNextUChar(UConverter *cnv, 18506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char **source, const char *sourceLimit, 18516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *err) { 18526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs args; 18536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar buffer[U16_MAX_LENGTH]; 18546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *s; 18556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 c; 18566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, length; 18576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check parameters */ 18596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(err==NULL || U_FAILURE(*err)) { 18606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xffff; 18616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv==NULL || source==NULL) { 18646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 18656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xffff; 18666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=*source; 18696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceLimit<s) { 18706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 18716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xffff; 18726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 18756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Make sure that the buffer sizes do not exceed the number range for 18766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * int32_t because some functions use the size (in units or bytes) 18776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * rather than comparing pointers, and because offsets are int32_t values. 18786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 18796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * size_t is guaranteed to be unsigned and large enough for the job. 18806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 18816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return with an error instead of adjusting the limits because we would 18826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * not be able to maintain the semantics that either the source must be 18836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * consumed or the target filled (unless an error occurs). 18846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * An adjustment would be sourceLimit=t+0x7fffffff; for example. 18856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 18866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s)) { 18876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ILLEGAL_ARGUMENT_ERROR; 18886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xffff; 18896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=U_SENTINEL; 18926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* flush the target overflow buffer */ 18946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->UCharErrorBufferLength>0) { 18956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *overflow; 18966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org overflow=cnv->UCharErrorBuffer; 18986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=0; 18996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=cnv->UCharErrorBufferLength; 19006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_NEXT(overflow, i, length, c); 19016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* move the remaining overflow contents up to the beginning */ 19036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((cnv->UCharErrorBufferLength=(int8_t)(length-i))>0) { 19046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(cnv->UCharErrorBuffer, cnv->UCharErrorBuffer+i, 19056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBufferLength*U_SIZEOF_UCHAR); 19066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!U16_IS_LEAD(c) || i<length) { 19096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return c; 19106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 19126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Continue if the overflow buffer contained only a lead surrogate, 19136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in case the converter outputs single surrogates from complete 19146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * input sequences. 19156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 19166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 19196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * flush==TRUE is implied for ucnv_getNextUChar() 19206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 19216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * do not simply return even if s==sourceLimit because the converter may 19226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * not have seen flush==TRUE before 19236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 19246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* prepare the converter arguments */ 19266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.converter=cnv; 19276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.flush=TRUE; 19286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.offsets=NULL; 19296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.source=s; 19306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.sourceLimit=sourceLimit; 19316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.target=buffer; 19326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.targetLimit=buffer+1; 19336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.size=sizeof(args); 19346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(c<0) { 19366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 19376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * call the native getNextUChar() implementation if we are 19386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * at a character boundary (toULength==0) 19396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 19406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * unlike with _toUnicode(), getNextUChar() implementations must set 19416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * U_TRUNCATED_CHAR_FOUND for truncated input, 19426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in addition to setting toULength/toUBytes[] 19436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 19446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->toULength==0 && cnv->sharedData->impl->getNextUChar!=NULL) { 19456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=cnv->sharedData->impl->getNextUChar(&args, err); 19466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *source=s=args.source; 19476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*err==U_INDEX_OUTOFBOUNDS_ERROR) { 19486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the converter without calling the callback function */ 19496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(cnv, UCNV_RESET_TO_UNICODE, FALSE); 19506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0xffff; /* no output */ 19516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(U_SUCCESS(*err) && c>=0) { 19526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return c; 19536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 19546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * else fall through to use _toUnicode() because 19556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * UCNV_GET_NEXT_UCHAR_USE_TO_U: the native function did not want to handle it after all 19566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * U_FAILURE: call _toUnicode() for callback handling (do not output c) 19576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 19586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* convert to one UChar in buffer[0], or handle getNextUChar() errors */ 19626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _toUnicodeWithCallback(&args, err); 19636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*err==U_BUFFER_OVERFLOW_ERROR) { 19656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ZERO_ERROR; 19666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=0; 19696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=(int32_t)(args.target-buffer); 19706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 19716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* write the lead surrogate from the overflow buffer */ 19726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org buffer[0]=(UChar)c; 19736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.target=buffer+1; 19746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=0; 19756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=1; 19766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* buffer contents starts at i and ends before length */ 19796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*err)) { 19816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=0xffff; /* no output */ 19826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(length==0) { 19836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no input or only state changes */ 19846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_INDEX_OUTOFBOUNDS_ERROR; 19856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no need to reset explicitly because _toUnicodeWithCallback() did it */ 19866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=0xffff; /* no output */ 19876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 19886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=buffer[0]; 19896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=1; 19906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!U16_IS_LEAD(c)) { 19916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* consume c=buffer[0], done */ 19926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 19936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* got a lead surrogate, see if a trail surrogate follows */ 19946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar c2; 19956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->UCharErrorBufferLength>0) { 19976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* got overflow output from the conversion */ 19986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U16_IS_TRAIL(c2=cnv->UCharErrorBuffer[0])) { 19996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* got a trail surrogate, too */ 20006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=U16_GET_SUPPLEMENTARY(c, c2); 20016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* move the remaining overflow contents up to the beginning */ 20036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((--cnv->UCharErrorBufferLength)>0) { 20046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(cnv->UCharErrorBuffer, cnv->UCharErrorBuffer+1, 20056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBufferLength*U_SIZEOF_UCHAR); 20066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 20086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* c is an unpaired lead surrogate, just return it */ 20096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(args.source<sourceLimit) { 20116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* convert once more, to buffer[1] */ 20126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args.targetLimit=buffer+2; 20136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _toUnicodeWithCallback(&args, err); 20146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*err==U_BUFFER_OVERFLOW_ERROR) { 20156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err=U_ZERO_ERROR; 20166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=(int32_t)(args.target-buffer); 20196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(*err) && length==2 && U16_IS_TRAIL(c2=buffer[1])) { 20206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* got a trail surrogate, too */ 20216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=U16_GET_SUPPLEMENTARY(c, c2); 20226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=2; 20236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 20296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * move leftover output from buffer[i..length[ 20306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * into the beginning of the overflow buffer 20316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 20326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i<length) { 20336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* move further overflow back */ 20346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t delta=length-i; 20356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((length=cnv->UCharErrorBufferLength)>0) { 20366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(cnv->UCharErrorBuffer+delta, cnv->UCharErrorBuffer, 20376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length*U_SIZEOF_UCHAR); 20386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBufferLength=(int8_t)(length+delta); 20406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBuffer[0]=buffer[i++]; 20426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(delta>1) { 20436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->UCharErrorBuffer[1]=buffer[i]; 20446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *source=args.source; 20486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return c; 20496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 20506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ucnv_convert() and siblings ---------------------------------------------- */ 20526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 20546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv, 20556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char **target, const char *targetLimit, 20566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char **source, const char *sourceLimit, 20576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *pivotStart, UChar **pivotSource, 20586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar **pivotTarget, const UChar *pivotLimit, 20596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool reset, UBool flush, 20606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 20616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar pivotBuffer[CHUNK_SIZE]; 20626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *myPivotSource; 20636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *myPivotTarget; 20646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *s; 20656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *t; 20666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterToUnicodeArgs toUArgs; 20686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterFromUnicodeArgs fromUArgs; 20696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterConvert convert; 20706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* error checking */ 20726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 20736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 20746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( targetCnv==NULL || sourceCnv==NULL || 20776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source==NULL || *source==NULL || 20786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target==NULL || *target==NULL || targetLimit==NULL 20796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 20806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 20816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 20826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=*source; 20856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t=*target; 20866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((sourceLimit!=NULL && sourceLimit<s) || targetLimit<t) { 20876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 20886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 20896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 20906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 20916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 20926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Make sure that the buffer sizes do not exceed the number range for 20936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * int32_t. See ucnv_toUnicode() for a more detailed comment. 20946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 20956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( 20966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (sourceLimit!=NULL && ((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s)) || 20976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) 20986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 20996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 21006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 21016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pivotStart==NULL) { 21046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!flush) { 21056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* streaming conversion requires an explicit pivot buffer */ 21066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 21076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 21086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* use the stack pivot buffer */ 21116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org myPivotSource=myPivotTarget=pivotStart=pivotBuffer; 21126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotSource=(UChar **)&myPivotSource; 21136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotTarget=&myPivotTarget; 21146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotLimit=pivotBuffer+CHUNK_SIZE; 21156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if( pivotStart>=pivotLimit || 21166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotSource==NULL || *pivotSource==NULL || 21176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotTarget==NULL || *pivotTarget==NULL || 21186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotLimit==NULL 21196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 21206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 21216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 21226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceLimit==NULL) { 21256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get limit of single-byte-NUL-terminated source string */ 21266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceLimit=uprv_strchr(*source, 0); 21276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reset) { 21306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_resetToUnicode(sourceCnv); 21316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_resetFromUnicode(targetCnv); 21326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pivotSource=*pivotTarget=pivotStart; 21336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(targetCnv->charErrorBufferLength>0) { 21346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output the targetCnv overflow buffer */ 21356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(ucnv_outputOverflowFromUnicode(targetCnv, target, targetLimit, NULL, pErrorCode)) { 21366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* U_BUFFER_OVERFLOW_ERROR */ 21376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 21386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* *target has moved, therefore stop using t */ 21406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( !flush && 21426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetCnv->preFromULength>=0 && *pivotSource==*pivotTarget && 21436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceCnv->UCharErrorBufferLength==0 && sourceCnv->preToULength>=0 && s==sourceLimit 21446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 21456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the fromUnicode overflow buffer is emptied and there is no new input: we are done */ 21466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 21476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Is direct-UTF-8 conversion available? */ 21516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( sourceCnv->sharedData->staticData->conversionType==UCNV_UTF8 && 21526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetCnv->sharedData->impl->fromUTF8!=NULL 21536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 21546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org convert=targetCnv->sharedData->impl->fromUTF8; 21556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if( targetCnv->sharedData->staticData->conversionType==UCNV_UTF8 && 21566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceCnv->sharedData->impl->toUTF8!=NULL 21576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 21586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org convert=sourceCnv->sharedData->impl->toUTF8; 21596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 21606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org convert=NULL; 21616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 21646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If direct-UTF-8 conversion is available, then we use a smaller 21656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * pivot buffer for error handling and partial matches 21666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * so that we quickly return to direct conversion. 21676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 21686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 32 is large enough for UCNV_EXT_MAX_UCHARS and UCNV_ERROR_BUFFER_LENGTH. 21696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 21706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We could reduce the pivot buffer size further, at the cost of 21716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * buffer overflows from callbacks. 21726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The pivot buffer should not be smaller than the maximum number of 21736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * fromUnicode extension table input UChars 21746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (for m:n conversion, see 21756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * targetCnv->sharedData->mbcs.extIndexes[UCNV_EXT_COUNT_UCHARS]) 21766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or 2 for surrogate pairs. 21776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 21786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Too small a buffer can cause thrashing between pivoting and direct 21796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * conversion, with function call overhead outweighing the benefits 21806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * of direct conversion. 21816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 21826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(convert!=NULL && (pivotLimit-pivotStart)>32) { 21836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotLimit=pivotStart+32; 21846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 21856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* prepare the converter arguments */ 21876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.converter=targetCnv; 21886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.flush=FALSE; 21896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.offsets=NULL; 21906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.target=*target; 21916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.targetLimit=targetLimit; 21926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.size=sizeof(fromUArgs); 21936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 21946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.converter=sourceCnv; 21956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.flush=flush; 21966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.offsets=NULL; 21976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.source=s; 21986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.sourceLimit=sourceLimit; 21996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.targetLimit=pivotLimit; 22006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.size=sizeof(toUArgs); 22016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * TODO: Consider separating this function into two functions, 22046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * extracting exactly the conversion loop, 22056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for readability and to reduce the set of visible variables. 22066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 22076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Otherwise stop using s and t from here on. 22086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=t=NULL; 22106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * conversion loop 22136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 22146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The sequence of steps in the loop may appear backward, 22156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * but the principle is simple: 22166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In the chain of 22176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * source - sourceCnv overflow - pivot - targetCnv overflow - target 22186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * empty out later buffers before refilling them from earlier ones. 22196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 22206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The targetCnv overflow buffer is flushed out only once before the loop. 22216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 22236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if(pivot not empty or error or replay or flush fromUnicode) { 22256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * fromUnicode(pivot -> target); 22266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 22276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 22286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For pivoting conversion; and for direct conversion for 22296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * error callback handling and flushing the replay buffer. 22306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( *pivotSource<*pivotTarget || 22326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_FAILURE(*pErrorCode) || 22336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetCnv->preFromULength<0 || 22346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.flush 22356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 22366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.source=*pivotSource; 22376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.sourceLimit=*pivotTarget; 22386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _fromUnicodeWithCallback(&fromUArgs, pErrorCode); 22396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 22406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* target overflow, or conversion error */ 22416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pivotSource=(UChar *)fromUArgs.source; 22426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 22436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * _fromUnicodeWithCallback() must have consumed the pivot contents 22476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (*pivotSource==*pivotTarget) since it returned with U_SUCCESS() 22486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The pivot buffer is empty; reset it so we start at pivotStart. */ 22526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pivotSource=*pivotTarget=pivotStart; 22536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if(sourceCnv overflow buffer not empty) { 22566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * move(sourceCnv overflow buffer -> pivot); 22576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * continue; 22586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 22596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* output the sourceCnv overflow buffer */ 22616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceCnv->UCharErrorBufferLength>0) { 22626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(ucnv_outputOverflowToUnicode(sourceCnv, pivotTarget, pivotLimit, NULL, pErrorCode)) { 22636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* U_BUFFER_OVERFLOW_ERROR */ 22646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 22656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 22676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * check for end of input and break if done 22716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 22726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Checking both flush and fromUArgs.flush ensures that the converters 22736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * have been called with the flush flag set if the ucnv_convertEx() 22746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * caller set it. 22756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( toUArgs.source==sourceLimit && 22776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceCnv->preToULength>=0 && sourceCnv->toULength==0 && 22786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (!flush || fromUArgs.flush) 22796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 22806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* done successfully */ 22816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 22826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 22846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 22856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * use direct conversion if available 22866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * but not if continuing a partial match 22876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * or flushing the toUnicode replay buffer 22886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 22896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(convert!=NULL && targetCnv->preFromUFirstCP<0 && sourceCnv->preToULength==0) { 22906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_USING_DEFAULT_WARNING) { 22916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* remove a warning that may be set by this function */ 22926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 22936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 22946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org convert(&fromUArgs, &toUArgs, pErrorCode); 22956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 22966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 22976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(U_FAILURE(*pErrorCode)) { 22986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceCnv->toULength>0) { 22996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Fall through to calling _toUnicodeWithCallback() 23016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for callback handling. 23026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 23036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The pivot buffer will be reset with 23046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * *pivotSource=*pivotTarget=pivotStart; 23056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * which indicates a toUnicode error to the caller 23066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (*pivotSource==pivotStart shows no pivot UChars consumed). 23076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 23096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Indicate a fromUnicode error to the caller 23116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (*pivotSource>pivotStart shows some pivot UChars consumed). 23126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pivotSource=*pivotTarget=pivotStart+1; 23146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Loop around to calling _fromUnicodeWithCallbacks() 23166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for callback handling. 23176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 23196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(*pErrorCode==U_USING_DEFAULT_WARNING) { 23216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * No error, but the implementation requested to temporarily 23236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * fall back to pivoting. 23246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 23266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The following else branches are almost identical to the end-of-input 23286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * handling in _toUnicodeWithCallback(). 23296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Avoid calling it just for the end of input. 23306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(flush && sourceCnv->toULength>0) { /* flush==toUArgs.flush */ 23326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the entire input stream is consumed 23346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and there is a partial, truncated input sequence left 23356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* inject an error and continue with callback handling */ 23386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_TRUNCATED_CHAR_FOUND; 23396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 23406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* input consumed */ 23416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flush) { 23426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the converters without calling the callback functions */ 23436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(sourceCnv, UCNV_RESET_TO_UNICODE, FALSE); 23446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _reset(targetCnv, UCNV_RESET_FROM_UNICODE, FALSE); 23456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* done successfully */ 23486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 23496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * toUnicode(source -> pivot); 23546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 23556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For pivoting conversion; and for direct conversion for 23566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * error callback handling, continuing partial matches 23576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and flushing the replay buffer. 23586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 23596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The pivot buffer is empty and reset. 23606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUArgs.target=pivotStart; /* ==*pivotTarget */ 23626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* toUArgs.targetLimit=pivotLimit; already set before the loop */ 23636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _toUnicodeWithCallback(&toUArgs, pErrorCode); 23646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pivotTarget=toUArgs.target; 23656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { 23666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* pivot overflow: continue with the conversion loop */ 23676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 23686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(U_FAILURE(*pErrorCode) || (!flush && *pivotTarget==pivotStart)) { 23696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* conversion error, or there was nothing left to convert */ 23706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 23716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * else: 23746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * _toUnicodeWithCallback() wrote into the pivot buffer, 23756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * continue with fromUnicode conversion. 23766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 23776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Set the fromUnicode flush flag if we flush and if toUnicode has 23786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * processed the end of the input. 23796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( flush && toUArgs.source==sourceLimit && 23816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceCnv->preToULength>=0 && 23826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceCnv->UCharErrorBufferLength==0 23836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 23846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fromUArgs.flush=TRUE; 23856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 23876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 23896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The conversion loop is exited when one of the following is true: 23906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - the entire source text has been converted successfully to the target buffer 23916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - a target buffer overflow occurred 23926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * - a conversion error occurred 23936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 23946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *source=toUArgs.source; 23966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *target=fromUArgs.target; 23976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 23986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* terminate the target buffer if possible */ 23996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(flush && U_SUCCESS(*pErrorCode)) { 24006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*target!=targetLimit) { 24016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org **target=0; 24026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_STRING_NOT_TERMINATED_WARNING) { 24036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 24046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 24066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_STRING_NOT_TERMINATED_WARNING; 24076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 24106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* internal implementation of ucnv_convert() etc. with preflighting */ 24126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 24136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_internalConvert(UConverter *outConverter, UConverter *inConverter, 24146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *target, int32_t targetCapacity, 24156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *source, int32_t sourceLength, 24166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 24176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar pivotBuffer[CHUNK_SIZE]; 24186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *pivot, *pivot2; 24196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *myTarget; 24216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *sourceLimit; 24226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *targetLimit; 24236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t targetLength=0; 24246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set up */ 24266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceLength<0) { 24276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceLimit=uprv_strchr(source, 0); 24286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 24296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceLimit=source+sourceLength; 24306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if there is no input data, we're done */ 24336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(source==sourceLimit) { 24346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateChars(target, targetCapacity, 0, pErrorCode); 24356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivot=pivot2=pivotBuffer; 24386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org myTarget=target; 24396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLength=0; 24406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(targetCapacity>0) { 24426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* perform real conversion */ 24436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLimit=target+targetCapacity; 24446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_convertEx(outConverter, inConverter, 24456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &myTarget, targetLimit, 24466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &source, sourceLimit, 24476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotBuffer, &pivot, &pivot2, pivotBuffer+CHUNK_SIZE, 24486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FALSE, 24496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 24506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 24516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLength=(int32_t)(myTarget-target); 24526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 24556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If the output buffer is exhausted (or we are only "preflighting"), we need to stop writing 24566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to it but continue the conversion in order to store in targetCapacity 24576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the number of bytes that was required. 24586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 24596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || targetCapacity==0) 24606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 24616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char targetBuffer[CHUNK_SIZE]; 24626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLimit=targetBuffer+CHUNK_SIZE; 24646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 24656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ZERO_ERROR; 24666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org myTarget=targetBuffer; 24676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_convertEx(outConverter, inConverter, 24686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &myTarget, targetLimit, 24696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &source, sourceLimit, 24706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pivotBuffer, &pivot, &pivot2, pivotBuffer+CHUNK_SIZE, 24716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FALSE, 24726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TRUE, 24736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 24746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLength+=(int32_t)(myTarget-targetBuffer); 24756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR); 24766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* done with preflighting, set warnings and errors as appropriate */ 24786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateChars(target, targetCapacity, targetLength, pErrorCode); 24796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no need to call u_terminateChars() because ucnv_convertEx() took care of that */ 24826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return targetLength; 24836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 24846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 24866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_convert(const char *toConverterName, const char *fromConverterName, 24876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *target, int32_t targetCapacity, 24886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *source, int32_t sourceLength, 24896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 24906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter in, out; /* stack-allocated */ 24916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *inConverter, *outConverter; 24926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t targetLength; 24936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 24956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 24966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 24976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 24986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( source==NULL || sourceLength<-1 || 24996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetCapacity<0 || (targetCapacity>0 && target==NULL) 25006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 25016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 25026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 25036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if there is no input data, we're done */ 25066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceLength==0 || (sourceLength<0 && *source==0)) { 25076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateChars(target, targetCapacity, 0, pErrorCode); 25086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* create the converters */ 25116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org inConverter=ucnv_createConverter(&in, fromConverterName, pErrorCode); 25126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 25136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 25146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org outConverter=ucnv_createConverter(&out, toConverterName, pErrorCode); 25176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 25186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_close(inConverter); 25196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 25206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLength=ucnv_internalConvert(outConverter, inConverter, 25236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetCapacity, 25246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source, sourceLength, 25256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 25266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_close(inConverter); 25286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_close(outConverter); 25296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return targetLength; 25316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 25326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* @internal */ 25346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 25356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_convertAlgorithmic(UBool convertToAlgorithmic, 25366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterType algorithmicType, 25376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *cnv, 25386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *target, int32_t targetCapacity, 25396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *source, int32_t sourceLength, 25406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 25416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter algoConverterStatic; /* stack-allocated */ 25426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *algoConverter, *to, *from; 25436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t targetLength; 25446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 25466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 25476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( cnv==NULL || source==NULL || sourceLength<-1 || 25506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetCapacity<0 || (targetCapacity>0 && target==NULL) 25516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 25526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 25536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 25546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if there is no input data, we're done */ 25576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceLength==0 || (sourceLength<0 && *source==0)) { 25586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateChars(target, targetCapacity, 0, pErrorCode); 25596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* create the algorithmic converter */ 25626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org algoConverter=ucnv_createAlgorithmicConverter(&algoConverterStatic, algorithmicType, 25636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "", 0, pErrorCode); 25646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 25656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 25666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* reset the other converter */ 25696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(convertToAlgorithmic) { 25706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* cnv->Unicode->algo */ 25716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_resetToUnicode(cnv); 25726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org to=algoConverter; 25736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org from=cnv; 25746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 25756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* algo->Unicode->cnv */ 25766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_resetFromUnicode(cnv); 25776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org from=algoConverter; 25786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org to=cnv; 25796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 25806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org targetLength=ucnv_internalConvert(to, from, 25826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetCapacity, 25836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source, sourceLength, 25846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 25856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucnv_close(algoConverter); 25876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return targetLength; 25896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 25906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 25916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 25926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_toAlgorithmic(UConverterType algorithmicType, 25936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverter *cnv, 25946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *target, int32_t targetCapacity, 25956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *source, int32_t sourceLength, 25966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 25976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_convertAlgorithmic(TRUE, algorithmicType, cnv, 25986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetCapacity, 25996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source, sourceLength, 26006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 26016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 26046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_fromAlgorithmic(UConverter *cnv, 26056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UConverterType algorithmicType, 26066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *target, int32_t targetCapacity, 26076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *source, int32_t sourceLength, 26086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 26096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_convertAlgorithmic(FALSE, algorithmicType, cnv, 26106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org target, targetCapacity, 26116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source, sourceLength, 26126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pErrorCode); 26136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UConverterType U_EXPORT2 26166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getType(const UConverter* converter) 26176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 26186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int8_t type = converter->sharedData->staticData->conversionType; 26196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_LEGACY_CONVERSION 26206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type == UCNV_MBCS) { 26216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ucnv_MBCSGetType(converter); 26226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 26246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UConverterType)type; 26256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 26286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getStarters(const UConverter* converter, 26296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool starters[256], 26306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* err) 26316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 26326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err == NULL || U_FAILURE(*err)) { 26336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 26346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(converter->sharedData->impl->getStarters != NULL) { 26376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org converter->sharedData->impl->getStarters(converter, starters, err); 26386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 26396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_ILLEGAL_ARGUMENT_ERROR; 26406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UAmbiguousConverter *ucnv_getAmbiguous(const UConverter *cnv) 26446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 26456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode errorCode; 26466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *name; 26476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 26486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv==NULL) { 26506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 26516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_ZERO_ERROR; 26546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name=ucnv_getName(cnv, &errorCode); 26556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { 26566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 26576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<(int32_t)(sizeof(ambiguousConverters)/sizeof(UAmbiguousConverter)); ++i) 26606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 26616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(0==uprv_strcmp(name, ambiguousConverters[i].name)) 26626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 26636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ambiguousConverters+i; 26646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 26686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 26716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_fixFileSeparator(const UConverter *cnv, 26726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* source, 26736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sourceLength) { 26746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UAmbiguousConverter *a; 26756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 26766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar variant5c; 26776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv==NULL || source==NULL || sourceLength<=0 || (a=ucnv_getAmbiguous(cnv))==NULL) 26796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 26806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 26816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org variant5c=a->variant5c; 26846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<sourceLength; ++i) { 26856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(source[i]==variant5c) { 26866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org source[i]=0x5c; 26876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 26896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBool U_EXPORT2 26926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_isAmbiguous(const UConverter *cnv) { 26936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UBool)(ucnv_getAmbiguous(cnv)!=NULL); 26946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 26956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 26966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 26976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_setFallback(UConverter *cnv, UBool usesFallback) 26986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 26996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnv->useFallback = usesFallback; 27006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBool U_EXPORT2 27036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_usesFallback(const UConverter *cnv) 27046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 27056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return cnv->useFallback; 27066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 27096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getInvalidChars (const UConverter * converter, 27106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *errBytes, 27116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int8_t * len, 27126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 27136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 27146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err == NULL || U_FAILURE(*err)) 27156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 27176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len == NULL || errBytes == NULL || converter == NULL) 27196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_ILLEGAL_ARGUMENT_ERROR; 27216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 27226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*len < converter->invalidCharLength) 27246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_INDEX_OUTOFBOUNDS_ERROR; 27266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 27276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((*len = converter->invalidCharLength) > 0) 27296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy (errBytes, converter->invalidCharBuffer, *len); 27316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 27356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_getInvalidUChars (const UConverter * converter, 27366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *errChars, 27376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int8_t * len, 27386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode * err) 27396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 27406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (err == NULL || U_FAILURE(*err)) 27416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 27436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len == NULL || errChars == NULL || converter == NULL) 27456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_ILLEGAL_ARGUMENT_ERROR; 27476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 27486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*len < converter->invalidUCharLength) 27506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *err = U_INDEX_OUTOFBOUNDS_ERROR; 27526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 27536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((*len = converter->invalidUCharLength) > 0) 27556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 27566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy (errChars, converter->invalidUCharBuffer, sizeof(UChar) * (*len)); 27576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 27596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define SIG_MAX_LEN 5 27616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const char* U_EXPORT2 27636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_detectUnicodeSignature( const char* source, 27646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sourceLength, 27656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t* signatureLength, 27666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* pErrorCode) { 27676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t dummy; 27686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initial 0xa5 bytes: make sure that if we read <SIG_MAX_LEN 27706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * bytes we don't misdetect something 27716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 27726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char start[SIG_MAX_LEN]={ '\xa5', '\xa5', '\xa5', '\xa5', '\xa5' }; 27736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int i = 0; 27746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((pErrorCode==NULL) || U_FAILURE(*pErrorCode)){ 27766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 27776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(source == NULL || sourceLength < -1){ 27806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 27816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 27826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(signatureLength == NULL) { 27856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org signatureLength = &dummy; 27866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(sourceLength==-1){ 27896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceLength=(int32_t)uprv_strlen(source); 27906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(i<sourceLength&& i<SIG_MAX_LEN){ 27946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start[i]=source[i]; 27956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i++; 27966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 27976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 27986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start[0] == '\xFE' && start[1] == '\xFF') { 27996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=2; 28006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-16BE"; 28016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[0] == '\xFF' && start[1] == '\xFE') { 28026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start[2] == '\x00' && start[3] =='\x00') { 28036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=4; 28046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-32LE"; 28056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 28066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=2; 28076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-16LE"; 28086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[0] == '\xEF' && start[1] == '\xBB' && start[2] == '\xBF') { 28106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=3; 28116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-8"; 28126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[0] == '\x00' && start[1] == '\x00' && 28136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start[2] == '\xFE' && start[3]=='\xFF') { 28146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=4; 28156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-32BE"; 28166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[0] == '\x0E' && start[1] == '\xFE' && start[2] == '\xFF') { 28176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=3; 28186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "SCSU"; 28196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[0] == '\xFB' && start[1] == '\xEE' && start[2] == '\x28') { 28206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=3; 28216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "BOCU-1"; 28226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[0] == '\x2B' && start[1] == '\x2F' && start[2] == '\x76') { 28236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 28246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * UTF-7: Initial U+FEFF is encoded as +/v8 or +/v9 or +/v+ or +/v/ 28256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * depending on the second UTF-16 code unit. 28266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Detect the entire, closed Unicode mode sequence +/v8- for only U+FEFF 28276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if it occurs. 28286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 28296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * So far we have +/v 28306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 28316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start[3] == '\x38' && start[4] == '\x2D') { 28326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 5 bytes +/v8- */ 28336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=5; 28346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-7"; 28356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start[3] == '\x38' || start[3] == '\x39' || start[3] == '\x2B' || start[3] == '\x2F') { 28366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 4 bytes +/v8 or +/v9 or +/v+ or +/v/ */ 28376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=4; 28386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-7"; 28396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(start[0]=='\xDD' && start[1]== '\x73'&& start[2]=='\x66' && start[3]=='\x73'){ 28416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=4; 28426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return "UTF-EBCDIC"; 28436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no known Unicode signature byte sequence recognized */ 28476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *signatureLength=0; 28486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 28496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 28526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_fromUCountPending(const UConverter* cnv, UErrorCode* status) 28536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 28546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 28556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 28566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv == NULL){ 28586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 28596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 28606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->preFromUFirstCP >= 0){ 28636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U16_LENGTH(cnv->preFromUFirstCP)+cnv->preFromULength ; 28646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(cnv->preFromULength < 0){ 28656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -cnv->preFromULength ; 28666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(cnv->fromUChar32 > 0){ 28676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 1; 28686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 28706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 28746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_toUCountPending(const UConverter* cnv, UErrorCode* status){ 28756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 28776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 28786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv == NULL){ 28806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 28816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 28826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnv->preToULength > 0){ 28856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return cnv->preToULength ; 28866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(cnv->preToULength < 0){ 28876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -cnv->preToULength; 28886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(cnv->toULength > 0){ 28896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return cnv->toULength; 28906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 28926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 28936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 28946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBool U_EXPORT2 28956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgucnv_isFixedWidth(UConverter *cnv, UErrorCode *status){ 28966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(*status)) { 28976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 28986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 28996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 29006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cnv == NULL) { 29016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 29026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 29036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 29046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 29056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (ucnv_getType(cnv)) { 29066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_SBCS: 29076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_DBCS: 29086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_UTF32_BigEndian: 29096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_UTF32_LittleEndian: 29106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_UTF32: 29116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCNV_US_ASCII: 29126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 29136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 29146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 29156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 29166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 29176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 29186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 29196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 29206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Hey, Emacs, please set the following: 29216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 29226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Local Variables: 29236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * indent-tabs-mode: nil 29246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * End: 29256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 29266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2927