1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * COPYRIGHT: 459d709d503bab6e2b61931737e662dd293b40578ccornelius * Copyright (c) 1996-2013, International Business Machines Corporation and 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************** 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 8103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * uconv_bld.cpp: 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Defines functions that are used in the creation/initialization/deletion 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * of converters and related structures. 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * uses uconv_io.h routines to access disk information 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is used by ucnv.h to implement public API create/delete/flushCache routines 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Modification History: 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Date Name Description 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 06/20/2000 helena OS/400 port changes; mostly typecast. 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 06/29/2000 helena Major rewrite of the callback interface. 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_CONVERSION 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/putil.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uloc.h" 3059d709d503bab6e2b61931737e662dd293b40578ccornelius#include "mutex.h" 31103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "putilimp.h" 3259d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "utracimp.h" 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_io.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_bld.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnvmbcs.h" 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_ext.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_cnv.h" 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_imp.h" 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uhash.h" 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h" 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucln_cmn.h" 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustr_cnv.h" 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruextern void UCNV_DEBUG_LOG(char *what, char *who, void *p, int l); 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UCNV_DEBUG_LOG(x,y,z) UCNV_DEBUG_LOG(x,y,z,__LINE__) 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define UCNV_DEBUG_LOG(x,y,z) 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterSharedData * const 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruconverterData[UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES]={ 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, NULL, 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UCONFIG_NO_LEGACY_CONVERSION 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_MBCSData, 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_Latin1Data, 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_UTF8Data, &_UTF16BEData, &_UTF16LEData, &_UTF32BEData, &_UTF32LEData, 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UCONFIG_NO_LEGACY_CONVERSION 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, NULL, NULL, NULL, NULL, NULL, 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, NULL, NULL, NULL, NULL, NULL, 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_ISO2022Data, 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_LMBCSData1,&_LMBCSData2, &_LMBCSData3, &_LMBCSData4, &_LMBCSData5, &_LMBCSData6, 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_LMBCSData8,&_LMBCSData11,&_LMBCSData16,&_LMBCSData17,&_LMBCSData18,&_LMBCSData19, 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_HZData, 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_SCSUData, 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UCONFIG_NO_LEGACY_CONVERSION 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_ISCIIData, 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_ASCIIData, 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho &_UTF7Data, &_Bocu1Data, &_UTF16Data, &_UTF32Data, &_CESU8Data, &_IMAPData, 92103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 93103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if UCONFIG_NO_LEGACY_CONVERSION 94103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius NULL, 95103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#else 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho &_CompoundTextData 97103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Please keep this in binary sorted order for getAlgorithmicTypeFromName. 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Also the name should be in lower case and all spaces, dashes and underscores 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru removed 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic struct { 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterType type; 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} const cnvNameType[] = { 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "bocu1", UCNV_BOCU1 }, 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "cesu8", UCNV_CESU8 }, 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "hz",UCNV_HZ }, 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "imapmailboxname", UCNV_IMAP_MAILBOX }, 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "iscii", UCNV_ISCII }, 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "iso2022", UCNV_ISO_2022 }, 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "iso88591", UCNV_LATIN_1 }, 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs1", UCNV_LMBCS_1 }, 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs11",UCNV_LMBCS_11 }, 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs16",UCNV_LMBCS_16 }, 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs17",UCNV_LMBCS_17 }, 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs18",UCNV_LMBCS_18 }, 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs19",UCNV_LMBCS_19 }, 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs2", UCNV_LMBCS_2 }, 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs3", UCNV_LMBCS_3 }, 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs4", UCNV_LMBCS_4 }, 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs5", UCNV_LMBCS_5 }, 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs6", UCNV_LMBCS_6 }, 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs8", UCNV_LMBCS_8 }, 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "scsu", UCNV_SCSU }, 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "usascii", UCNV_US_ASCII }, 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16", UCNV_UTF16 }, 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16be", UCNV_UTF16_BigEndian }, 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16le", UCNV_UTF16_LittleEndian }, 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_IS_BIG_ENDIAN 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16oppositeendian", UCNV_UTF16_LittleEndian }, 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16platformendian", UCNV_UTF16_BigEndian }, 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16oppositeendian", UCNV_UTF16_BigEndian}, 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16platformendian", UCNV_UTF16_LittleEndian }, 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32", UCNV_UTF32 }, 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32be", UCNV_UTF32_BigEndian }, 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32le", UCNV_UTF32_LittleEndian }, 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_IS_BIG_ENDIAN 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32oppositeendian", UCNV_UTF32_LittleEndian }, 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32platformendian", UCNV_UTF32_BigEndian }, 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32oppositeendian", UCNV_UTF32_BigEndian }, 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32platformendian", UCNV_UTF32_LittleEndian }, 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf7", UCNV_UTF7 }, 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "utf8", UCNV_UTF8 }, 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { "x11compoundtext", UCNV_COMPOUND_TEXT} 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*initializes some global variables */ 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UHashtable *SHARED_DATA_HASHTABLE = NULL; 16354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex cnvCacheMutex = U_MUTEX_INITIALIZER; /* Mutex for synchronizing cnv cache access. */ 16454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius /* Note: the global mutex is used for */ 16554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius /* reference count updates. */ 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char **gAvailableConverters = NULL; 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t gAvailableConverterCount = 0; 16959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gAvailableConvertersInitOnce = U_INITONCE_INITIALIZER; 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 17285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* This contains the resolved converter name. So no further alias lookup is needed again. */ 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic char gDefaultConverterNameBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH + 1]; /* +1 for NULL */ 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char *gDefaultConverterName = NULL; 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruIf the default converter is an algorithmic converter, this is the cached value. 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruWe don't cache a full UConverter and clone it because ucnv_clone doesn't have 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruless overhead than an algorithmic open. We don't cache non-algorithmic converters 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querubecause ucnv_flushCache must be able to unload the default converter and its table. 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterSharedData *gDefaultAlgorithmicSharedData = NULL; 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Does gDefaultConverterName have a converter option and require extra parsing? */ 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool gDefaultConverterContainsOption; 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif /* !U_CHARSET_IS_UTF8 */ 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char DATA_TYPE[] = "cnv"; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 19259d709d503bab6e2b61931737e662dd293b40578ccornelius/* ucnv_flushAvailableConverterCache. This is only called from ucnv_cleanup(). 19359d709d503bab6e2b61931737e662dd293b40578ccornelius * If it is ever to be called from elsewhere, synchronization 19459d709d503bab6e2b61931737e662dd293b40578ccornelius * will need to be considered. 19559d709d503bab6e2b61931737e662dd293b40578ccornelius */ 19685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void 19785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houcnv_flushAvailableConverterCache() { 19859d709d503bab6e2b61931737e662dd293b40578ccornelius gAvailableConverterCount = 0; 19985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (gAvailableConverters) { 20085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free((char **)gAvailableConverters); 20185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho gAvailableConverters = NULL; 20285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 20359d709d503bab6e2b61931737e662dd293b40578ccornelius gAvailableConvertersInitOnce.reset(); 20485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 20585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_cleanup - delete all storage held by the converter cache, except any */ 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* in use by open converters. */ 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Not thread safe. */ 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Not supported API. */ 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV ucnv_cleanup(void) { 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_flushCache(); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) { 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uhash_close(SHARED_DATA_HASHTABLE); 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SHARED_DATA_HASHTABLE = NULL; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Isn't called from flushCache because other threads may have preexisting references to the table. */ 21885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_flushAvailableConverterCache(); 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 22085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterName = NULL; 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterNameBuffer[0] = 0; 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterContainsOption = FALSE; 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultAlgorithmicSharedData = NULL; 22585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (SHARED_DATA_HASHTABLE == NULL); 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV 231103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusisCnvAcceptable(void * /*context*/, 232103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const char * /*type*/, const char * /*name*/, 23385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UDataInfo *pInfo) { 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UBool)( 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->size>=20 && 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->sizeofUChar==U_SIZEOF_UCHAR && 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x63 && /* dataFormat="cnvt" */ 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x6e && 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x76 && 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x74 && 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==6); /* Everything will be version 6 */ 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Un flatten shared data from a UDATA.. 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterSharedData* 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_data_unFlattenClone(UConverterLoadArgs *pArgs, UDataMemory *pData, UErrorCode *status) 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* UDataInfo info; -- necessary only if some converters have different formatVersion */ 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint8_t *raw = (const uint8_t *)udata_getMemory(pData); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterStaticData *source = (const UConverterStaticData *) raw; 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *data; 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterType type = (UConverterType)source->conversionType; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*status)) 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( (uint16_t)type >= UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES || 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterData[type] == NULL || 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterData[type]->referenceCounter != 1 || 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source->structSize != sizeof(UConverterStaticData)) 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_INVALID_TABLE_FORMAT; 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = (UConverterSharedData *)uprv_malloc(sizeof(UConverterSharedData)); 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data == NULL) { 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy initial values from the static structure for this type */ 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(data, converterData[type], sizeof(UConverterSharedData)); 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 /* made UConverterMBCSTable part of UConverterSharedData -- markus 20031107 */ 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It would be much more efficient if the table were a direct member, not a pointer. 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * However, that would add to the size of all UConverterSharedData objects 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * even if they do not use this table (especially algorithmic ones). 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If this changes, then the static templates from converterData[type] 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * need more entries. 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In principle, it would be cleaner if the load() function below 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * allocated the table. 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->table = (UConverterTable *)uprv_malloc(sizeof(UConverterTable)); 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data->table == NULL) { 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data); 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(data->table, 0, sizeof(UConverterTable)); 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->staticData = source; 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->sharedDataCached = FALSE; 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* fill in fields from the loaded data */ 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->dataMemory = (void*)pData; /* for future use */ 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data->impl->load != NULL) { 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->impl->load(data, pArgs, raw + source->structSize, status); 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*status)) { 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data->table); 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data); 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data; 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Takes an alias name gets an actual converter file name 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *goes to disk and opens it. 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *allocates the memory and returns a new UConverter object 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err) 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory *data; 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *sharedData; 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_LOAD); 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) { 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg); 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = udata_openChoice(pArgs->pkg, DATA_TYPE, pArgs->name, isCnvAcceptable, NULL, err); 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData = ucnv_data_unFlattenClone(pArgs, data, err); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_close(data); 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * TODO Store pkg in a field in the shared data so that delta-only converters 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * can load base converters from the same package. 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If the pkg name is longer than the field, then either do not load the converter 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * in the first place, or just set the pkg field to "". 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(sharedData, *err); 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return sharedData; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*returns a converter type from a string 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterSharedData * 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetAlgorithmicTypeFromName(const char *realName) 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t mid, start, limit; 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t lastMid; 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int result; 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char strippedName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Lower case and remove ignoreable characters. */ 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_stripForCompare(strippedName, realName); 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do a binary search for the alias */ 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = 0; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = sizeof(cnvNameType)/sizeof(cnvNameType[0]); 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = limit; 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastMid = UINT32_MAX; 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;;) { 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = (uint32_t)((start + limit) / 2); 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lastMid == mid) { /* Have we moved? */ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* We haven't moved, and it wasn't found. */ 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastMid = mid; 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = uprv_strcmp(strippedName, cnvNameType[mid].name); 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result < 0) { 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = mid; 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (result > 0) { 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = mid; 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return converterData[cnvNameType[mid].type]; 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Based on the number of known converters, this determines how many times larger 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* the shared data hash table should be. When on small platforms, or just a couple 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* of converters are used, this number should be 2. When memory is plentiful, or 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* when ucnv_countAvailable is ever used with a lot of available converters, 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* this should be 4. 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Larger numbers reduce the number of hash collisions, but use more memory. 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UCNV_CACHE_LOAD_FACTOR 2 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Puts the shared data in the static hashtable SHARED_DATA_HASHTABLE */ 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Will always be called with the cnvCacheMutex alrady being held */ 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* by the calling function. */ 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Stores the shared data in the SHARED_DATA_HASHTABLE 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param data The shared data 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_shareConverterData(UConverterSharedData * data) 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*Lazy evaluates the Hashtable itself */ 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*void *sanity = NULL;*/ 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars, NULL, 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_countKnownConverters(&err)*UCNV_CACHE_LOAD_FACTOR, 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &err); 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup); 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(err)) 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* ### check to see if the element is not already there! */ 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sanity = ucnv_getSharedConverterData (data->staticData->name); 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sanity != NULL) 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("put:overwrite!",data->staticData->name,sanity); 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("put:chk",data->staticData->name,sanity); 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Mark it shared */ 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->sharedDataCached = TRUE; 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uhash_put(SHARED_DATA_HASHTABLE, 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (void*) data->staticData->name, /* Okay to cast away const as long as 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru keyDeleter == NULL */ 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data, 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &err); 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("put", data->staticData->name,data); 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Look up a converter name in the shared data cache. */ 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* cnvCacheMutex must be held by the caller to protect the hash table. */ 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* gets the shared data from the SHARED_DATA_HASHTABLE (might return NULL if it isn't there) 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param name The name of the shared data 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the shared data from the SHARED_DATA_HASHTABLE 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterSharedData * 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getSharedConverterData(const char *name) 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*special case when no Table has yet been created we return NULL */ 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *rc; 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc = (UConverterSharedData*)uhash_get(SHARED_DATA_HASHTABLE, name); 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("get",name,rc); 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rc; 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*frees the string of memory blocks associates with a sharedConverter 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *if and only if the referenceCounter == 0 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Deletes (frees) the Shared data it's passed. first it checks the referenceCounter to 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * see if anyone is using it, if not it frees all the memory stemming from sharedConverterData and 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * returns TRUE, 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * otherwise returns FALSE 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param sharedConverterData The shared data 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return if not it frees all the memory stemming from sharedConverterData and 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * returns TRUE, otherwise returns FALSE 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_deleteSharedConverterData(UConverterSharedData * deadSharedData) 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_UNLOAD); 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA2(UTRACE_OPEN_CLOSE, "unload converter %s shared data %p", deadSharedData->staticData->name, deadSharedData); 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (deadSharedData->referenceCounter > 0) { 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE((int32_t)FALSE); 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (deadSharedData->impl->unload != NULL) { 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru deadSharedData->impl->unload(deadSharedData); 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(deadSharedData->dataMemory != NULL) 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory *data = (UDataMemory*)deadSharedData->dataMemory; 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_close(data); 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(deadSharedData->table != NULL) 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(deadSharedData->table); 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the static data is actually owned by the shared data */ 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* enable if we ever have this situation. */ 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(deadSharedData->staticDataOwned == TRUE) /* see ucnv_bld.h */ 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free((void*)deadSharedData->staticData); 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Zap it ! */ 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(deadSharedData->0, sizeof(*deadSharedData)); 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(deadSharedData); 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE((int32_t)TRUE); 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Load a non-algorithmic converter. 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex). 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverterSharedData * 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_load(UConverterLoadArgs *pArgs, UErrorCode *err) { 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData; 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(err == NULL || U_FAILURE(*err)) { 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pArgs->pkg != NULL && *pArgs->pkg != 0) { 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* application-provided converters are not currently cached */ 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return createConverterFromFile(pArgs, err); 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData = ucnv_getSharedConverterData(pArgs->name); 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mySharedConverterData == NULL) 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*Not cached, we need to stream it in from file */ 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData = createConverterFromFile(pArgs, err); 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err) || (mySharedConverterData == NULL)) 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 56485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else if (!pArgs->onlyTestIsLoadable) 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* share it with other library clients */ 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_shareConverterData(mySharedConverterData); 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The data for this converter was already in the cache. */ 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Update the reference counter on the shared data: one more client */ 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData->referenceCounter++; 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return mySharedConverterData; 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Unload a non-algorithmic converter. 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It must be sharedData->referenceCounter != ~0 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and this function must be called inside umtx_lock(&cnvCacheMutex). 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 585103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI void 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_unload(UConverterSharedData *sharedData) { 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sharedData != NULL) { 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (sharedData->referenceCounter > 0) { 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData->referenceCounter--; 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((sharedData->referenceCounter <= 0)&&(sharedData->sharedDataCached == FALSE)) { 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_deleteSharedConverterData(sharedData); 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 598103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CFUNC void 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData) 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Checking whether it's an algorithic converter is okay 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in multithreaded applications because the value never changes. 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Don't check referenceCounter for any other value. 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 606103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(sharedData != NULL && sharedData->referenceCounter != (uint32_t)~0) { 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_unload(sharedData); 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 613103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CFUNC void 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_incrementRefCount(UConverterSharedData *sharedData) 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 61685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 61785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Checking whether it's an algorithic converter is okay 61885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho in multithreaded applications because the value never changes. 61985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Don't check referenceCounter for any other value. 62085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 621103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(sharedData != NULL && sharedData->referenceCounter != (uint32_t)~0) { 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData->referenceCounter++; 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 62885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* 62985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * *pPieces must be initialized. 63085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * The name without options will be copied to pPieces->cnvName. 63185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * The locale and options will be copied to pPieces only if present in inName, 63285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * otherwise the existing values in pPieces remain. 63385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * *pArgs will be set to the pPieces values. 63485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruparseConverterOptions(const char *inName, 63785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces *pPieces, 63885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs *pArgs, 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 64185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho char *cnvName = pPieces->cnvName; 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char c; 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 64585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name=inName; 64685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->locale=pPieces->locale; 64785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=pPieces->options; 64885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the converter name itself to cnvName */ 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (++len>=UCNV_MAX_CONVERTER_NAME_LENGTH) { 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; /* bad name */ 65385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->cnvName[0]=0; 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *cnvName++=c; 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName++; 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *cnvName=0; 66085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name=pPieces->cnvName; 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* parse options. No more name copying should occur. */ 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((c=*inName)!=0) { 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c==UCNV_OPTION_SEP_CHAR) { 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++inName; 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* inName is behind an option separator */ 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uprv_strncmp(inName, "locale=", 7)==0) { 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not modify locale itself in case we have multiple locale options */ 67185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho char *dest=pPieces->locale; 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the locale option value */ 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName+=7; 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len=0; 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++inName; 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(++len>=ULOC_FULLNAME_CAPACITY) { 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; /* bad name */ 68185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->locale[0]=0; 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=c; 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest=0; 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(uprv_strncmp(inName, "version=", 8)==0) { 68985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* copy the version option value into bits 3..0 of pPieces->options */ 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName+=8; 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=*inName; 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c==0) { 69385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=(pPieces->options&=~UCNV_OPTION_VERSION); 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if((uint8_t)(c-'0')<10) { 69685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=pPieces->options=(pPieces->options&~UCNV_OPTION_VERSION)|(uint32_t)(c-'0'); 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++inName; 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(uprv_strncmp(inName, "swaplfnl", 8)==0) { 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName+=8; 70185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=(pPieces->options|=UCNV_OPTION_SWAP_LFNL); 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* add processing for new options here with another } else if(uprv_strncmp(inName, "option-name=", XX)==0) { */ 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* ignore any other options until we define some */ 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(((c = *inName++) != 0) && (c != UCNV_OPTION_SEP_CHAR)) { 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c==0) { 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Logic determines if the converter is Algorithmic AND/OR cached 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *depending on that: 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -we either go to get data from disk and cache it (Data=TRUE, Cached=False) 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -Get it from a Hashtable (Data=X, Cached=TRUE) 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -Call dataConverter initializer (Data=TRUE, Cached=TRUE) 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -Call AlgorithmicConverter initializer (Data=FALSE, Cached=TRUE) 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 721103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CFUNC UConverterSharedData * 72285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houcnv_loadSharedData(const char *converterName, 72385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces *pPieces, 72485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs *pArgs, 72585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode * err) { 72685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 72785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs; 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData = NULL; 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode internalErrorCode = U_ZERO_ERROR; 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mayContainOption = TRUE; 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool checkForAlgorithmic = TRUE; 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) { 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 73785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(pPieces == NULL) { 73885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(pArgs != NULL) { 73985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Bad: We may set pArgs pointers to stackPieces fields 74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * which will be invalid after this function returns. 74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *err = U_INTERNAL_PROGRAM_ERROR; 74485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 74585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 74685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces = &stackPieces; 747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 74885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(pArgs == NULL) { 74985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_memset(&stackArgs, 0, sizeof(stackArgs)); 75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.size = (int32_t)sizeof(stackArgs); 75185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs = &stackArgs; 75285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 75385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->cnvName[0] = 0; 75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->locale[0] = 0; 75685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->options = 0; 757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 75885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = converterName; 75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->locale = pPieces->locale; 76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options = pPieces->options; 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* In case "name" is NULL we want to open the default converter. */ 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converterName == NULL) { 76485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if U_CHARSET_IS_UTF8 76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = "UTF-8"; 76685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return (UConverterSharedData *)converterData[UCNV_UTF8]; 76785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else 768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Call ucnv_getDefaultName first to query the name from the OS. */ 76985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = ucnv_getDefaultName(); 77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (pArgs->name == NULL) { 771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_MISSING_RESOURCE_ERROR; 772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData = (UConverterSharedData *)gDefaultAlgorithmicSharedData; 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru checkForAlgorithmic = FALSE; 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mayContainOption = gDefaultConverterContainsOption; 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the default converter name is already canonical */ 77885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 78085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else if(UCNV_FAST_IS_UTF8(converterName)) { 781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* fastpath for UTF-8 */ 78285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = "UTF-8"; 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UConverterSharedData *)converterData[UCNV_UTF8]; 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* separate the converter name from the options */ 78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(converterName, pPieces, pArgs, err); 788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Very bad name used. */ 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the canonical converter name */ 79485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = ucnv_io_getConverterName(pArgs->name, &mayContainOption, &internalErrorCode); 79585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(internalErrorCode) || pArgs->name == NULL) { 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set the input name in case the converter was added 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * without updating the alias table, or when there is no alias table 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 80085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = pPieces->cnvName; 8018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (internalErrorCode == U_AMBIGUOUS_ALIAS_WARNING) { 8028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius *err = U_AMBIGUOUS_ALIAS_WARNING; 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* separate the converter name from the options */ 80785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(mayContainOption && pArgs->name != pPieces->cnvName) { 80885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(pArgs->name, pPieces, pArgs, err); 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the shared data for an algorithmic converter, if it is one */ 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (checkForAlgorithmic) { 81385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = (UConverterSharedData *)getAlgorithmicTypeFromName(pArgs->name); 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mySharedConverterData == NULL) 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* it is a data-based converter, get its shared data. */ 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Hold the cnvCacheMutex through the whole process of checking the */ 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* converter data cache, and adding new entries to the cache */ 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* to prevent other threads from modifying the cache during the */ 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* process. */ 82285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->nestedLoads=1; 82385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->pkg=NULL; 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 82685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = ucnv_load(pArgs, err); 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err) || (mySharedConverterData == NULL)) 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return mySharedConverterData; 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 837103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI UConverter * 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createConverter(UConverter *myUConverter, const char *converterName, UErrorCode * err) 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 84085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 841103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER; 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData; 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN); 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open converter %s", converterName); 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = ucnv_loadSharedData(converterName, &stackPieces, &stackArgs, err); 85085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 85185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter = ucnv_createConverterFromSharedData( 85285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter, mySharedConverterData, 85385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &stackArgs, 85485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho err); 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_EXIT_PTR_STATUS(myUConverter, *err); 85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return myUConverter; 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* exit with error */ 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 86785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CFUNC UBool 86885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houcnv_canCreateConverter(const char *converterName, UErrorCode *err) { 86985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverter myUConverter; 87085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 871103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER; 87285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterSharedData *mySharedConverterData; 87385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 87485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN); 87585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 87685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_SUCCESS(*err)) { 87785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_DATA1(UTRACE_OPEN_CLOSE, "test if can open converter %s", converterName); 87885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 87985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.onlyTestIsLoadable=TRUE; 88085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = ucnv_loadSharedData(converterName, &stackPieces, &stackArgs, err); 88185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_createConverterFromSharedData( 88285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &myUConverter, mySharedConverterData, 88385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &stackArgs, 88485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho err); 88585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_unloadSharedDataIfReady(mySharedConverterData); 88685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 88785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 88885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_EXIT_STATUS(*err); 88985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return U_SUCCESS(*err); 89085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 89185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverter * 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createAlgorithmicConverter(UConverter *myUConverter, 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterType type, 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *locale, uint32_t options, 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv; 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterSharedData *sharedData; 899103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER; 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_ALGORITHMIC); 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open algorithmic converter type %d", (int32_t)type); 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(type<0 || UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES<=type) { 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR); 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData = converterData[type]; 91185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 91285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Checking whether it's an algorithic converter is okay 91385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho in multithreaded applications because the value never changes. 91485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Don't check referenceCounter for any other value. 91585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 916103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(sharedData == NULL || sharedData->referenceCounter != (uint32_t)~0) { 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* not a valid type, or not an algorithmic converter */ 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR); 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 92385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.name = ""; 92485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.options = options; 92585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.locale=locale; 92685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho cnv = ucnv_createConverterFromSharedData( 92785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter, (UConverterSharedData *)sharedData, 92885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &stackArgs, err); 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(cnv, *err); 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return cnv; 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 934103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CFUNC UConverter* 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createConverterFromPackage(const char *packageName, const char *converterName, UErrorCode * err) 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *myUConverter; 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData; 93985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 940103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER; 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_PACKAGE); 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) { 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA2(UTRACE_OPEN_CLOSE, "open converter %s from package %s", converterName, packageName); 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* first, get the options out of the converterName string */ 95285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.cnvName[0] = 0; 95385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.locale[0] = 0; 95485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.options = 0; 95585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(converterName, &stackPieces, &stackArgs, err); 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Very bad name used. */ 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 96185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.nestedLoads=1; 96285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.pkg=packageName; 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* open the data, unflatten the shared structure */ 96585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = createConverterFromFile(&stackArgs, err); 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* create the actual converter */ 97385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter = ucnv_createConverterFromSharedData(NULL, mySharedConverterData, &stackArgs, err); 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(myUConverter); 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(myUConverter, *err); 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myUConverter; 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 986103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CFUNC UConverter* 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createConverterFromSharedData(UConverter *myUConverter, 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData, 98985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs *pArgs, 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool isCopyLocal; 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 99485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_FAILURE(*err)) { 99585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_unloadSharedDataIfReady(mySharedConverterData); 99685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return myUConverter; 99785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(myUConverter == NULL) 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myUConverter = (UConverter *) uprv_malloc (sizeof (UConverter)); 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(myUConverter == NULL) 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_MEMORY_ALLOCATION_ERROR; 100485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_unloadSharedDataIfReady(mySharedConverterData); 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru isCopyLocal = FALSE; 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru isCopyLocal = TRUE; 1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* initialize the converter */ 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(myUConverter, 0, sizeof(UConverter)); 1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myUConverter->isCopyLocal = isCopyLocal; 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*myUConverter->isExtraLocal = FALSE;*/ /* Set by the memset call */ 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myUConverter->sharedData = mySharedConverterData; 101785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->options = pArgs->options; 101885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(!pArgs->onlyTestIsLoadable) { 101985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->preFromUFirstCP = U_SENTINEL; 102085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->fromCharErrorBehaviour = UCNV_TO_U_DEFAULT_CALLBACK; 102185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->fromUCharErrorBehaviour = UCNV_FROM_U_DEFAULT_CALLBACK; 102285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->toUnicodeStatus = mySharedConverterData->toUnicodeStatus; 102385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->maxBytesPerUChar = mySharedConverterData->staticData->maxBytesPerChar; 102485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->subChar1 = mySharedConverterData->staticData->subChar1; 102585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->subCharLen = mySharedConverterData->staticData->subCharLen; 102685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->subChars = (uint8_t *)myUConverter->subUChars; 102785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_memcpy(myUConverter->subChars, mySharedConverterData->staticData->subChar, myUConverter->subCharLen); 102885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->toUCallbackReason = UCNV_ILLEGAL; /* default reason to invoke (*fromCharErrorBehaviour) */ 102985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mySharedConverterData->impl->open != NULL) { 103285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData->impl->open(myUConverter, pArgs, err); 103385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_FAILURE(*err) && !pArgs->onlyTestIsLoadable) { 103485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* don't ucnv_close() if onlyTestIsLoadable because not fully initialized */ 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(myUConverter); 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myUConverter; 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Frees all shared immutable objects that aren't referred to (reference count = 0) 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_flushCache () 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedData = NULL; 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t pos; 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t tableDeletedNum = 0; 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UHashElement *e; 105227f654740f2a26ad62a5c155af9199af9e69b889claireho /*UErrorCode status = U_ILLEGAL_ARGUMENT_ERROR;*/ 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, remaining; 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_FLUSH_CACHE); 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Close the default converter without creating a new one so that everything will be flushed. */ 105827f654740f2a26ad62a5c155af9199af9e69b889claireho u_flushDefaultConverter(); 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*if shared data hasn't even been lazy evaluated yet 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return 0 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) { 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE((int32_t)0); 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*creates an enumeration to iterate through every element in the 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * table 1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Synchronization: holding cnvCacheMutex will prevent any other thread from 1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * accessing or modifying the hash table during the iteration. 1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The reference count of an entry may be decremented by 1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ucnv_close while the iteration is in process, but this is 1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * benign. It can't be incremented (in ucnv_createConverter()) 1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * because the sequence of looking up in the cache + incrementing 1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is protected by cnvCacheMutex. 1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * double loop: A delta/extension-only converter has a pointer to its base table's 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * shared data; the first iteration of the outer loop may see the delta converter 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * before the base converter, and unloading the delta converter may get the base 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * converter's reference counter down to 0. 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i = 0; 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remaining = 0; 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = -1; 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((e = uhash_nextElement (SHARED_DATA_HASHTABLE, &pos)) != NULL) 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedData = (UConverterSharedData *) e->value.pointer; 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*deletes only if reference counter == 0 */ 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mySharedData->referenceCounter == 0) 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tableDeletedNum++; 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("del",mySharedData->staticData->name,mySharedData); 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uhash_removeElement(SHARED_DATA_HASHTABLE, e); 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedData->sharedDataCached = FALSE; 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_deleteSharedConverterData (mySharedData); 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++remaining; 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(++i == 1 && remaining > 0); 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA1(UTRACE_INFO, "ucnv_flushCache() exits with %d converters remaining", remaining); 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE(tableDeletedNum); 1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tableDeletedNum; 1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* available converters list --------------------------------------------------- */ 1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 111859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initAvailableConvertersList(UErrorCode &errCode) { 111959d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gAvailableConverterCount == 0); 112059d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gAvailableConverters == NULL); 1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 112259d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup); 112359d709d503bab6e2b61931737e662dd293b40578ccornelius UEnumeration *allConvEnum = ucnv_openAllNames(&errCode); 112459d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t allConverterCount = uenum_count(allConvEnum, &errCode); 112559d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(errCode)) { 112659d709d503bab6e2b61931737e662dd293b40578ccornelius return; 112759d709d503bab6e2b61931737e662dd293b40578ccornelius } 1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 112959d709d503bab6e2b61931737e662dd293b40578ccornelius /* We can't have more than "*converterTable" converters to open */ 113059d709d503bab6e2b61931737e662dd293b40578ccornelius gAvailableConverters = (const char **) uprv_malloc(allConverterCount * sizeof(char*)); 113159d709d503bab6e2b61931737e662dd293b40578ccornelius if (!gAvailableConverters) { 113259d709d503bab6e2b61931737e662dd293b40578ccornelius errCode = U_MEMORY_ALLOCATION_ERROR; 113359d709d503bab6e2b61931737e662dd293b40578ccornelius return; 113459d709d503bab6e2b61931737e662dd293b40578ccornelius } 1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 113659d709d503bab6e2b61931737e662dd293b40578ccornelius /* Open the default converter to make sure that it has first dibs in the hash table. */ 113759d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode localStatus = U_ZERO_ERROR; 113859d709d503bab6e2b61931737e662dd293b40578ccornelius UConverter tempConverter; 113959d709d503bab6e2b61931737e662dd293b40578ccornelius ucnv_close(ucnv_createConverter(&tempConverter, NULL, &localStatus)); 1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 114159d709d503bab6e2b61931737e662dd293b40578ccornelius gAvailableConverterCount = 0; 1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 114359d709d503bab6e2b61931737e662dd293b40578ccornelius for (int32_t idx = 0; idx < allConverterCount; idx++) { 114459d709d503bab6e2b61931737e662dd293b40578ccornelius localStatus = U_ZERO_ERROR; 114559d709d503bab6e2b61931737e662dd293b40578ccornelius const char *converterName = uenum_next(allConvEnum, NULL, &localStatus); 114659d709d503bab6e2b61931737e662dd293b40578ccornelius if (ucnv_canCreateConverter(converterName, &localStatus)) { 114759d709d503bab6e2b61931737e662dd293b40578ccornelius gAvailableConverters[gAvailableConverterCount++] = converterName; 1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 115059d709d503bab6e2b61931737e662dd293b40578ccornelius 115159d709d503bab6e2b61931737e662dd293b40578ccornelius uenum_close(allConvEnum); 115259d709d503bab6e2b61931737e662dd293b40578ccornelius} 115359d709d503bab6e2b61931737e662dd293b40578ccornelius 115459d709d503bab6e2b61931737e662dd293b40578ccornelius 115559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UBool haveAvailableConverterList(UErrorCode *pErrorCode) { 115659d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gAvailableConvertersInitOnce, &initAvailableConvertersList, *pErrorCode); 115759d709d503bab6e2b61931737e662dd293b40578ccornelius return U_SUCCESS(*pErrorCode); 1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC uint16_t 1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_bld_countAvailableConverters(UErrorCode *pErrorCode) { 1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAvailableConverterList(pErrorCode)) { 1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gAvailableConverterCount; 1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC const char * 1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_bld_getAvailableConverter(uint16_t n, UErrorCode *pErrorCode) { 1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAvailableConverterList(pErrorCode)) { 1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n < gAvailableConverterCount) { 1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gAvailableConverters[n]; 1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; 1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* default converter name --------------------------------------------------- */ 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 118185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCopy the canonical converter name. 1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getDefaultName must be thread safe, which can call this function. 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setDefaultName calls this function and it doesn't have to be 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruthread safe because there is no reliable/safe way to reset the 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconverter in use in all threads. If you did reset the converter, you 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruwould not be sure that retrieving a default converter for one string 1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruwould be the same type of default converter for a successive string. 1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSince the name is a returned via ucnv_getDefaultName without copying, 1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruyou shouldn't be modifying or deleting the string from a separate thread. 1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1194103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline void 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruinternalSetName(const char *name, UErrorCode *status) { 119685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 1197103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER; 1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length=(int32_t)(uprv_strlen(name)); 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool containsOption = (UBool)(uprv_strchr(name, UCNV_OPTION_SEP_CHAR) != NULL); 1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterSharedData *algorithmicSharedData; 1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.name = name; 1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(containsOption) { 120485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.cnvName[0] = 0; 120585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.locale[0] = 0; 120685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.options = 0; 120785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(name, &stackPieces, &stackArgs, status); 120885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_FAILURE(*status)) { 120985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 121085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 121285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho algorithmicSharedData = getAlgorithmicTypeFromName(stackArgs.name); 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultAlgorithmicSharedData = algorithmicSharedData; 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterContainsOption = containsOption; 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(gDefaultConverterNameBuffer, name, length); 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterNameBuffer[length]=0; 122085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 122185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* gDefaultConverterName MUST be the last global var set by this function. */ 122285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* It is the variable checked in ucnv_getDefaultName() to see if initialization is required. */ 122359d709d503bab6e2b61931737e662dd293b40578ccornelius // But there is nothing here preventing that from being reordered, either by the compiler 122459d709d503bab6e2b61931737e662dd293b40578ccornelius // or hardware. I'm adding the mutex to ucnv_getDefaultName for now. UMTX_CHECK is not enough. 122559d709d503bab6e2b61931737e662dd293b40578ccornelius // -- Andy 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterName = gDefaultConverterNameBuffer; 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup); 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 123285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In order to be really thread-safe, the get function would have to take 1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a buffer parameter and copy the current string inside a mutex block. 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This implementation only tries to be really thread-safe while 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * setting the name. 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It assumes that setting a pointer is atomic. 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getDefaultName() { 124485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if U_CHARSET_IS_UTF8 124585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return "UTF-8"; 124685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* local variable to be thread-safe */ 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name; 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 125159d709d503bab6e2b61931737e662dd293b40578ccornelius Concurrent calls to ucnv_getDefaultName must be thread safe, 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru but ucnv_setDefaultName is not thread safe. 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 125459d709d503bab6e2b61931737e662dd293b40578ccornelius { 125559d709d503bab6e2b61931737e662dd293b40578ccornelius icu::Mutex lock(&cnvCacheMutex); 125659d709d503bab6e2b61931737e662dd293b40578ccornelius name = gDefaultConverterName; 125759d709d503bab6e2b61931737e662dd293b40578ccornelius } 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(name==NULL) { 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv = NULL; 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = uprv_getDefaultCodepage(); 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the name is there, test it out and get the canonical name with options */ 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(name != NULL) { 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv = ucnv_open(name, &errorCode); 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(errorCode) && cnv != NULL) { 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = ucnv_getName(cnv, &errorCode); 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(name == NULL || name[0] == 0 1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || U_FAILURE(errorCode) || cnv == NULL 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || uprv_strlen(name)>=sizeof(gDefaultConverterNameBuffer)) 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Panic time, let's use a fallback. */ 1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if (U_CHARSET_FAMILY == U_ASCII_FAMILY) 1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = "US-ASCII"; 1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is no 'algorithmic' converter for EBCDIC */ 1280103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_OS390 1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = "ibm-1047_P100-1995" UCNV_SWAP_LFNL_OPTION_STRING; 1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = "ibm-37_P100-1995"; 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru internalSetName(name, &errorCode); 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The close may make the current name go away. */ 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(cnv); 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 129485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 129754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_CHARSET_IS_UTF8 129854dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI void U_EXPORT2 ucnv_setDefaultName(const char *) {} 129954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#else 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThis function is not thread safe, and it can't be thread safe. 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSee internalSetName or the API reference for details. 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setDefaultName(const char *converterName) { 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(converterName==NULL) { 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset to the default codepage */ 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterName=NULL; 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv = NULL; 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name = NULL; 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the name is there, test it out and get the canonical name with options */ 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv = ucnv_open(converterName, &errorCode); 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(errorCode) && cnv != NULL) { 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = ucnv_getName(cnv, &errorCode); 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(errorCode) && name!=NULL) { 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru internalSetName(name, &errorCode); 1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else this converter is bad to use. Don't change it to a bad value. */ 1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The close may make the current name go away. */ 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(cnv); 132727f654740f2a26ad62a5c155af9199af9e69b889claireho 132827f654740f2a26ad62a5c155af9199af9e69b889claireho /* reset the converter cache */ 132927f654740f2a26ad62a5c155af9199af9e69b889claireho u_flushDefaultConverter(); 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 133254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* data swapping ------------------------------------------------------------ */ 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* most of this might belong more properly into ucnvmbcs.c, but that is so large */ 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_swap(const UDataSwapper *ds, 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataInfo *pInfo; 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t headerSize; 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint8_t *inBytes; 1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t *outBytes; 1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t offset, count, staticDataSize; 1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t size; 1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterStaticData *inStaticData; 1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterStaticData *outStaticData; 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const _MBCSHeader *inMBCSHeader; 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _MBCSHeader *outMBCSHeader; 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _MBCSHeader mbcsHeader; 1359c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru uint32_t mbcsHeaderLength; 1360c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru UBool noFromU=FALSE; 1361c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t outputType; 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxFastUChar, mbcsIndexLength; 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const int32_t *inExtIndexes; 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t extOffset; 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check data format and format version */ 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!( 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x63 && /* dataFormat="cnvt" */ 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x6e && 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x76 && 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x74 && 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==6 && 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[1]>=2 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru )) { 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): data format %02x.%02x.%02x.%02x (format version %02x.%02x) is not recognized as an ICU .cnv conversion table\n", 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0], pInfo->formatVersion[1]); 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes=(const uint8_t *)inData+headerSize; 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes=(uint8_t *)outData+headerSize; 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the initial UConverterStaticData structure after the UDataInfo header */ 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inStaticData=(const UConverterStaticData *)inBytes; 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outStaticData=(UConverterStaticData *)outBytes; 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<0) { 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru staticDataSize=ds->readUInt32(inStaticData->structSize); 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-=headerSize; 1404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if( length<(int32_t)sizeof(UConverterStaticData) || 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uint32_t)length<(staticDataSize=ds->readUInt32(inStaticData->structSize)) 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after header) for an ICU .cnv conversion table\n", 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the static data */ 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inStaticData!=outStaticData) { 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outStaticData, inStaticData, staticDataSize); 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, &inStaticData->structSize, 4, 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &outStaticData->structSize, pErrorCode); 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, &inStaticData->codepage, 4, 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &outStaticData->codepage, pErrorCode); 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapInvChars(ds, inStaticData->name, (int32_t)uprv_strlen(inStaticData->name), 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outStaticData->name, pErrorCode); 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): error swapping converter name\n"); 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes+=staticDataSize; 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+=staticDataSize; 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-=(int32_t)staticDataSize; 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check for supported conversionType values */ 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inStaticData->conversionType==UCNV_MBCS) { 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap MBCS data */ 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inMBCSHeader=(const _MBCSHeader *)inBytes; 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outMBCSHeader=(_MBCSHeader *)outBytes; 1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1445103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(0<=length && length<(int32_t)sizeof(_MBCSHeader)) { 1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table\n", 1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1451c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if(inMBCSHeader->version[0]==4 && inMBCSHeader->version[1]>=1) { 1452c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru mbcsHeaderLength=MBCS_HEADER_V4_LENGTH; 1453c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } else if(inMBCSHeader->version[0]==5 && inMBCSHeader->version[1]>=3 && 1454c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ((mbcsHeader.options=ds->readUInt32(inMBCSHeader->options))& 1455c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru MBCS_OPT_UNKNOWN_INCOMPATIBLE_MASK)==0 1456c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ) { 1457c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru mbcsHeaderLength=mbcsHeader.options&MBCS_OPT_LENGTH_MASK; 1458c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru noFromU=(UBool)((mbcsHeader.options&MBCS_OPT_NO_FROM_U)!=0); 1459c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } else { 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unsupported _MBCSHeader.version %d.%d\n", 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inMBCSHeader->version[0], inMBCSHeader->version[1]); 1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(mbcsHeader.version, inMBCSHeader->version, 4); 1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.countStates= ds->readUInt32(inMBCSHeader->countStates); 1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.countToUFallbacks= ds->readUInt32(inMBCSHeader->countToUFallbacks); 1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.offsetToUCodeUnits= ds->readUInt32(inMBCSHeader->offsetToUCodeUnits); 1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.offsetFromUTable= ds->readUInt32(inMBCSHeader->offsetFromUTable); 1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.offsetFromUBytes= ds->readUInt32(inMBCSHeader->offsetFromUBytes); 1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.flags= ds->readUInt32(inMBCSHeader->flags); 1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.fromUBytesLength= ds->readUInt32(inMBCSHeader->fromUBytesLength); 1474c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /* mbcsHeader.options have been read above */ 1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru extOffset=(int32_t)(mbcsHeader.flags>>8); 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outputType=(uint8_t)mbcsHeader.flags; 1478c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if(noFromU && outputType==MBCS_OUTPUT_1) { 1479c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unsupported combination of makeconv --small with SBCS\n"); 1480c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1481c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru return 0; 1482c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* make sure that the output type is known */ 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(outputType) { 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_1: 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2: 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_3: 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_4: 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_3_EUC: 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_4_EUC: 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2_SISO: 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_EXT_ONLY: 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* OK */ 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unsupported MBCS output type 0x%x\n", 1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outputType); 1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* calculate the length of the MBCS data */ 1504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * utf8Friendly MBCS files (mbcsHeader.version 4.3) 1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * contain an additional mbcsIndex table: 1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * uint16_t[(maxFastUChar+1)>>6]; 1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * where maxFastUChar=((mbcsHeader.version[2]<<8)|0xff). 1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxFastUChar=0; 1512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsIndexLength=0; 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( outputType!=MBCS_OUTPUT_EXT_ONLY && outputType!=MBCS_OUTPUT_1 && 1514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.version[1]>=3 && (maxFastUChar=mbcsHeader.version[2])!=0 1515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxFastUChar=(maxFastUChar<<8)|0xff; 1517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsIndexLength=((maxFastUChar+1)>>6)*2; /* number of bytes */ 1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(extOffset==0) { 1521c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru size=(int32_t)(mbcsHeader.offsetFromUBytes+mbcsIndexLength); 1522c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if(!noFromU) { 1523c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru size+=(int32_t)mbcsHeader.fromUBytesLength; 1524c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* avoid compiler warnings - not otherwise necessary, and the value does not matter */ 1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inExtIndexes=NULL; 1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is extension data after the base data, see ucnv_ext.h */ 1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0 && length<(extOffset+UCNV_EXT_INDEXES_MIN_LENGTH*4)) { 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table with extension data\n", 1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inExtIndexes=(const int32_t *)(inBytes+extOffset); 1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size=extOffset+udata_readInt32(ds, inExtIndexes[UCNV_EXT_SIZE]); 1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<size) { 1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table\n", 1544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the data for inaccessible bytes */ 1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inBytes!=outBytes) { 1551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outBytes, inBytes, size); 1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1554c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /* swap the MBCSHeader, except for the version field */ 1555c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count=mbcsHeaderLength*4; 1556c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapArray32(ds, &inMBCSHeader->countStates, count-4, 1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &outMBCSHeader->countStates, pErrorCode); 1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(outputType==MBCS_OUTPUT_EXT_ONLY) { 1560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * extension-only file, 1562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * contains a base name instead of normal base table data 1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the base name, between the header and the extension data */ 1566c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const char *inBaseName=(const char *)inBytes+count; 1567c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru char *outBaseName=(char *)outBytes+count; 1568c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapInvChars(ds, inBaseName, (int32_t)uprv_strlen(inBaseName), 1569c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru outBaseName, pErrorCode); 1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* normal file with base table data */ 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the state table, 1kB per state */ 1574c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru offset=count; 1575c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count=mbcsHeader.countStates*1024; 1576c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1577c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru outBytes+offset, pErrorCode); 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the toUFallbacks[] */ 1580c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru offset+=count; 1581c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count=mbcsHeader.countToUFallbacks*8; 1582c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the unicodeCodeUnits[] */ 1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=mbcsHeader.offsetToUCodeUnits; 1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=mbcsHeader.offsetFromUTable-offset; 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* offset to the stage 1 table, independent of the outputType */ 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=mbcsHeader.offsetFromUTable; 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(outputType==MBCS_OUTPUT_1) { 1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* SBCS: swap the fromU tables, all 16 bits wide */ 1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=(mbcsHeader.offsetFromUBytes-offset)+mbcsHeader.fromUBytesLength; 1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* otherwise: swap the stage tables separately */ 1601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* stage 1 table: uint16_t[0x440 or 0x40] */ 1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inStaticData->unicodeMask&UCNV_HAS_SUPPLEMENTARY) { 1604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=0x440*2; /* for all of Unicode */ 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=0x40*2; /* only BMP */ 1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* stage 2 table: uint32_t[] */ 1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset+=count; 1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=mbcsHeader.offsetFromUBytes-offset; 1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* stage 3/result bytes: sometimes uint16_t[] or uint32_t[] */ 1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=mbcsHeader.offsetFromUBytes; 1619c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count= noFromU ? 0 : mbcsHeader.fromUBytesLength; 1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(outputType) { 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2: 1622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_3_EUC: 1623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2_SISO: 1624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_4: 1628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* just uint8_t[], nothing to swap */ 1633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mbcsIndexLength!=0) { 1637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset+=count; 1638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=mbcsIndexLength; 1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(extOffset!=0) { 1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the extension data */ 1647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes+=extOffset; 1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+=extOffset; 1649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap toUTable[] */ 1651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_INDEX]); 1652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_LENGTH]); 1653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, length*4, outBytes+offset, pErrorCode); 1654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap toUUChars[] */ 1656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_UCHARS_INDEX]); 1657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_UCHARS_LENGTH]); 1658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUTableUChars[] */ 1661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_UCHARS_INDEX]); 1662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_LENGTH]); 1663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUTableValues[] */ 1666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_VALUES_INDEX]); 1667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* same length as for fromUTableUChars[] */ 1668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, length*4, outBytes+offset, pErrorCode); 1669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no need to swap fromUBytes[] */ 1671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUStage12[] */ 1673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_12_INDEX]); 1674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_12_LENGTH]); 1675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUStage3[] */ 1678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3_INDEX]); 1679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3_LENGTH]); 1680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUStage3b[] */ 1683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3B_INDEX]); 1684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3B_LENGTH]); 1685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, length*4, outBytes+offset, pErrorCode); 1686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap indexes[] */ 1688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_INDEXES_LENGTH]); 1689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes, length*4, outBytes, pErrorCode); 1690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unknown conversionType=%d!=UCNV_MBCS\n", 1694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inStaticData->conversionType); 1695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+(int32_t)staticDataSize+size; 1700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */ 1703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1705