1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * COPYRIGHT: 427f654740f2a26ad62a5c155af9199af9e69b889claireho * Copyright (c) 1996-2010, International Business Machines Corporation and 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ******************************************************************** 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * uconv_bld.c: 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" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "utracimp.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_io.h" 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_bld.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnvmbcs.h" 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_ext.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_cnv.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_imp.h" 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uhash.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h" 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucln_cmn.h" 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustr_cnv.h" 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruextern void UCNV_DEBUG_LOG(char *what, char *who, void *p, int l); 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UCNV_DEBUG_LOG(x,y,z) UCNV_DEBUG_LOG(x,y,z,__LINE__) 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define UCNV_DEBUG_LOG(x,y,z) 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterSharedData * const 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruconverterData[UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES]={ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, NULL, 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UCONFIG_NO_LEGACY_CONVERSION 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_MBCSData, 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_Latin1Data, 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_UTF8Data, &_UTF16BEData, &_UTF16LEData, &_UTF32BEData, &_UTF32LEData, 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UCONFIG_NO_LEGACY_CONVERSION 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, NULL, NULL, NULL, NULL, NULL, 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, NULL, NULL, NULL, NULL, NULL, 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_ISO2022Data, 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_LMBCSData1,&_LMBCSData2, &_LMBCSData3, &_LMBCSData4, &_LMBCSData5, &_LMBCSData6, 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_LMBCSData8,&_LMBCSData11,&_LMBCSData16,&_LMBCSData17,&_LMBCSData18,&_LMBCSData19, 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_HZData, 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_SCSUData, 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if UCONFIG_NO_LEGACY_CONVERSION 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_ISCIIData, 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_ASCIIData, 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &_UTF7Data, &_Bocu1Data, &_UTF16Data, &_UTF32Data, &_CESU8Data, &_IMAPData 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Please keep this in binary sorted order for getAlgorithmicTypeFromName. 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Also the name should be in lower case and all spaces, dashes and underscores 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru removed 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic struct { 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name; 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterType type; 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} const cnvNameType[] = { 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "bocu1", UCNV_BOCU1 }, 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "cesu8", UCNV_CESU8 }, 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "hz",UCNV_HZ }, 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "imapmailboxname", UCNV_IMAP_MAILBOX }, 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "iscii", UCNV_ISCII }, 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "iso2022", UCNV_ISO_2022 }, 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "iso88591", UCNV_LATIN_1 }, 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs1", UCNV_LMBCS_1 }, 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs11",UCNV_LMBCS_11 }, 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs16",UCNV_LMBCS_16 }, 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs17",UCNV_LMBCS_17 }, 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs18",UCNV_LMBCS_18 }, 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs19",UCNV_LMBCS_19 }, 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs2", UCNV_LMBCS_2 }, 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs3", UCNV_LMBCS_3 }, 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs4", UCNV_LMBCS_4 }, 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs5", UCNV_LMBCS_5 }, 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs6", UCNV_LMBCS_6 }, 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "lmbcs8", UCNV_LMBCS_8 }, 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "scsu", UCNV_SCSU }, 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "usascii", UCNV_US_ASCII }, 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16", UCNV_UTF16 }, 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16be", UCNV_UTF16_BigEndian }, 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16le", UCNV_UTF16_LittleEndian }, 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_IS_BIG_ENDIAN 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16oppositeendian", UCNV_UTF16_LittleEndian }, 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16platformendian", UCNV_UTF16_BigEndian }, 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16oppositeendian", UCNV_UTF16_BigEndian}, 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf16platformendian", UCNV_UTF16_LittleEndian }, 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32", UCNV_UTF32 }, 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32be", UCNV_UTF32_BigEndian }, 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32le", UCNV_UTF32_LittleEndian }, 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_IS_BIG_ENDIAN 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32oppositeendian", UCNV_UTF32_LittleEndian }, 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32platformendian", UCNV_UTF32_BigEndian }, 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32oppositeendian", UCNV_UTF32_BigEndian }, 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf32platformendian", UCNV_UTF32_LittleEndian }, 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf7", UCNV_UTF7 }, 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { "utf8", UCNV_UTF8 } 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*initializes some global variables */ 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UHashtable *SHARED_DATA_HASHTABLE = NULL; 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UMTX cnvCacheMutex = NULL; /* Mutex for synchronizing cnv cache access. */ 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Note: the global mutex is used for */ 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reference count updates. */ 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char **gAvailableConverters = NULL; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t gAvailableConverterCount = 0; 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 16185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 16285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* This contains the resolved converter name. So no further alias lookup is needed again. */ 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic char gDefaultConverterNameBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH + 1]; /* +1 for NULL */ 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char *gDefaultConverterName = NULL; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruIf the default converter is an algorithmic converter, this is the cached value. 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruWe don't cache a full UConverter and clone it because ucnv_clone doesn't have 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruless overhead than an algorithmic open. We don't cache non-algorithmic converters 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querubecause ucnv_flushCache must be able to unload the default converter and its table. 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterSharedData *gDefaultAlgorithmicSharedData = NULL; 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Does gDefaultConverterName have a converter option and require extra parsing? */ 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool gDefaultConverterContainsOption; 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif /* !U_CHARSET_IS_UTF8 */ 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char DATA_TYPE[] = "cnv"; 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void 18385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houcnv_flushAvailableConverterCache() { 18485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (gAvailableConverters) { 18585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho umtx_lock(&cnvCacheMutex); 18685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho gAvailableConverterCount = 0; 18785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free((char **)gAvailableConverters); 18885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho gAvailableConverters = NULL; 18985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho umtx_unlock(&cnvCacheMutex); 19085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 19185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 19285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ucnv_cleanup - delete all storage held by the converter cache, except any */ 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* in use by open converters. */ 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Not thread safe. */ 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Not supported API. */ 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV ucnv_cleanup(void) { 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_flushCache(); 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) { 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uhash_close(SHARED_DATA_HASHTABLE); 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SHARED_DATA_HASHTABLE = NULL; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Isn't called from flushCache because other threads may have preexisting references to the table. */ 20585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_flushAvailableConverterCache(); 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterName = NULL; 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterNameBuffer[0] = 0; 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterContainsOption = FALSE; 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultAlgorithmicSharedData = NULL; 21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_destroy(&cnvCacheMutex); /* Don't worry about destroying the mutex even */ 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the hash table still exists. The mutex */ 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* will lazily re-init itself if needed. */ 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (SHARED_DATA_HASHTABLE == NULL); 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruisCnvAcceptable(void *context, 22285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const char *type, const char *name, 22385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UDataInfo *pInfo) { 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UBool)( 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->size>=20 && 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->sizeofUChar==U_SIZEOF_UCHAR && 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x63 && /* dataFormat="cnvt" */ 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x6e && 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x76 && 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x74 && 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==6); /* Everything will be version 6 */ 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Un flatten shared data from a UDATA.. 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterSharedData* 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_data_unFlattenClone(UConverterLoadArgs *pArgs, UDataMemory *pData, UErrorCode *status) 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* UDataInfo info; -- necessary only if some converters have different formatVersion */ 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint8_t *raw = (const uint8_t *)udata_getMemory(pData); 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterStaticData *source = (const UConverterStaticData *) raw; 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *data; 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterType type = (UConverterType)source->conversionType; 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*status)) 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( (uint16_t)type >= UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES || 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterData[type] == NULL || 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterData[type]->referenceCounter != 1 || 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source->structSize != sizeof(UConverterStaticData)) 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_INVALID_TABLE_FORMAT; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = (UConverterSharedData *)uprv_malloc(sizeof(UConverterSharedData)); 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data == NULL) { 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy initial values from the static structure for this type */ 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(data, converterData[type], sizeof(UConverterSharedData)); 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 /* made UConverterMBCSTable part of UConverterSharedData -- markus 20031107 */ 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It would be much more efficient if the table were a direct member, not a pointer. 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * However, that would add to the size of all UConverterSharedData objects 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * even if they do not use this table (especially algorithmic ones). 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If this changes, then the static templates from converterData[type] 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * need more entries. 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In principle, it would be cleaner if the load() function below 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * allocated the table. 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->table = (UConverterTable *)uprv_malloc(sizeof(UConverterTable)); 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data->table == NULL) { 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data); 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(data->table, 0, sizeof(UConverterTable)); 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->staticData = source; 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->sharedDataCached = FALSE; 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* fill in fields from the loaded data */ 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->dataMemory = (void*)pData; /* for future use */ 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data->impl->load != NULL) { 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->impl->load(data, pArgs, raw + source->structSize, status); 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*status)) { 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data->table); 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data); 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data; 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Takes an alias name gets an actual converter file name 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *goes to disk and opens it. 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *allocates the memory and returns a new UConverter object 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err) 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory *data; 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *sharedData; 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_LOAD); 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) { 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg); 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = udata_openChoice(pArgs->pkg, DATA_TYPE, pArgs->name, isCnvAcceptable, NULL, err); 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData = ucnv_data_unFlattenClone(pArgs, data, err); 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_close(data); 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * TODO Store pkg in a field in the shared data so that delta-only converters 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * can load base converters from the same package. 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If the pkg name is longer than the field, then either do not load the converter 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * in the first place, or just set the pkg field to "". 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(sharedData, *err); 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return sharedData; 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*returns a converter type from a string 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterSharedData * 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetAlgorithmicTypeFromName(const char *realName) 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t mid, start, limit; 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t lastMid; 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int result; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char strippedName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Lower case and remove ignoreable characters. */ 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_stripForCompare(strippedName, realName); 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do a binary search for the alias */ 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = 0; 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = sizeof(cnvNameType)/sizeof(cnvNameType[0]); 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = limit; 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastMid = UINT32_MAX; 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;;) { 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = (uint32_t)((start + limit) / 2); 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lastMid == mid) { /* Have we moved? */ 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* We haven't moved, and it wasn't found. */ 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastMid = mid; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = uprv_strcmp(strippedName, cnvNameType[mid].name); 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result < 0) { 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = mid; 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (result > 0) { 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = mid; 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return converterData[cnvNameType[mid].type]; 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Based on the number of known converters, this determines how many times larger 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* the shared data hash table should be. When on small platforms, or just a couple 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* of converters are used, this number should be 2. When memory is plentiful, or 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* when ucnv_countAvailable is ever used with a lot of available converters, 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* this should be 4. 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Larger numbers reduce the number of hash collisions, but use more memory. 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UCNV_CACHE_LOAD_FACTOR 2 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Puts the shared data in the static hashtable SHARED_DATA_HASHTABLE */ 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Will always be called with the cnvCacheMutex alrady being held */ 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* by the calling function. */ 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Stores the shared data in the SHARED_DATA_HASHTABLE 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param data The shared data 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_shareConverterData(UConverterSharedData * data) 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*Lazy evaluates the Hashtable itself */ 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*void *sanity = NULL;*/ 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars, NULL, 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_countKnownConverters(&err)*UCNV_CACHE_LOAD_FACTOR, 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &err); 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup); 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(err)) 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* ### check to see if the element is not already there! */ 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sanity = ucnv_getSharedConverterData (data->staticData->name); 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sanity != NULL) 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("put:overwrite!",data->staticData->name,sanity); 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("put:chk",data->staticData->name,sanity); 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Mark it shared */ 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data->sharedDataCached = TRUE; 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uhash_put(SHARED_DATA_HASHTABLE, 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (void*) data->staticData->name, /* Okay to cast away const as long as 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru keyDeleter == NULL */ 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data, 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &err); 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("put", data->staticData->name,data); 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Look up a converter name in the shared data cache. */ 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* cnvCacheMutex must be held by the caller to protect the hash table. */ 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* gets the shared data from the SHARED_DATA_HASHTABLE (might return NULL if it isn't there) 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param name The name of the shared data 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the shared data from the SHARED_DATA_HASHTABLE 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterSharedData * 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getSharedConverterData(const char *name) 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*special case when no Table has yet been created we return NULL */ 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *rc; 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc = (UConverterSharedData*)uhash_get(SHARED_DATA_HASHTABLE, name); 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("get",name,rc); 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rc; 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*frees the string of memory blocks associates with a sharedConverter 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *if and only if the referenceCounter == 0 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Deletes (frees) the Shared data it's passed. first it checks the referenceCounter to 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * see if anyone is using it, if not it frees all the memory stemming from sharedConverterData and 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * returns TRUE, 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * otherwise returns FALSE 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param sharedConverterData The shared data 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return if not it frees all the memory stemming from sharedConverterData and 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * returns TRUE, otherwise returns FALSE 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_deleteSharedConverterData(UConverterSharedData * deadSharedData) 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_UNLOAD); 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA2(UTRACE_OPEN_CLOSE, "unload converter %s shared data %p", deadSharedData->staticData->name, deadSharedData); 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (deadSharedData->referenceCounter > 0) { 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE((int32_t)FALSE); 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (deadSharedData->impl->unload != NULL) { 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru deadSharedData->impl->unload(deadSharedData); 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(deadSharedData->dataMemory != NULL) 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory *data = (UDataMemory*)deadSharedData->dataMemory; 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_close(data); 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(deadSharedData->table != NULL) 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(deadSharedData->table); 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the static data is actually owned by the shared data */ 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* enable if we ever have this situation. */ 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(deadSharedData->staticDataOwned == TRUE) /* see ucnv_bld.h */ 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free((void*)deadSharedData->staticData); 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Zap it ! */ 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(deadSharedData->0, sizeof(*deadSharedData)); 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(deadSharedData); 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE((int32_t)TRUE); 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Load a non-algorithmic converter. 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex). 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverterSharedData * 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_load(UConverterLoadArgs *pArgs, UErrorCode *err) { 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData; 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(err == NULL || U_FAILURE(*err)) { 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pArgs->pkg != NULL && *pArgs->pkg != 0) { 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* application-provided converters are not currently cached */ 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return createConverterFromFile(pArgs, err); 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData = ucnv_getSharedConverterData(pArgs->name); 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mySharedConverterData == NULL) 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*Not cached, we need to stream it in from file */ 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData = createConverterFromFile(pArgs, err); 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err) || (mySharedConverterData == NULL)) 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 55485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else if (!pArgs->onlyTestIsLoadable) 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* share it with other library clients */ 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_shareConverterData(mySharedConverterData); 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The data for this converter was already in the cache. */ 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Update the reference counter on the shared data: one more client */ 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData->referenceCounter++; 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return mySharedConverterData; 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Unload a non-algorithmic converter. 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It must be sharedData->referenceCounter != ~0 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and this function must be called inside umtx_lock(&cnvCacheMutex). 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_unload(UConverterSharedData *sharedData) { 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sharedData != NULL) { 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (sharedData->referenceCounter > 0) { 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData->referenceCounter--; 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((sharedData->referenceCounter <= 0)&&(sharedData->sharedDataCached == FALSE)) { 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_deleteSharedConverterData(sharedData); 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData) 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Checking whether it's an algorithic converter is okay 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in multithreaded applications because the value never changes. 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Don't check referenceCounter for any other value. 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sharedData != NULL && sharedData->referenceCounter != ~0) { 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_unload(sharedData); 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_incrementRefCount(UConverterSharedData *sharedData) 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 60685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 60785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Checking whether it's an algorithic converter is okay 60885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho in multithreaded applications because the value never changes. 60985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Don't check referenceCounter for any other value. 61085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(sharedData != NULL && sharedData->referenceCounter != ~0) { 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData->referenceCounter++; 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 61885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* 61985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * *pPieces must be initialized. 62085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * The name without options will be copied to pPieces->cnvName. 62185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * The locale and options will be copied to pPieces only if present in inName, 62285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * otherwise the existing values in pPieces remain. 62385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * *pArgs will be set to the pPieces values. 62485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruparseConverterOptions(const char *inName, 62785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces *pPieces, 62885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs *pArgs, 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 63185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho char *cnvName = pPieces->cnvName; 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char c; 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name=inName; 63685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->locale=pPieces->locale; 63785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=pPieces->options; 63885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the converter name itself to cnvName */ 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (++len>=UCNV_MAX_CONVERTER_NAME_LENGTH) { 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; /* bad name */ 64385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->cnvName[0]=0; 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *cnvName++=c; 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName++; 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *cnvName=0; 65085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name=pPieces->cnvName; 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* parse options. No more name copying should occur. */ 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((c=*inName)!=0) { 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c==UCNV_OPTION_SEP_CHAR) { 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++inName; 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* inName is behind an option separator */ 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uprv_strncmp(inName, "locale=", 7)==0) { 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not modify locale itself in case we have multiple locale options */ 66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho char *dest=pPieces->locale; 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the locale option value */ 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName+=7; 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len=0; 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++inName; 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(++len>=ULOC_FULLNAME_CAPACITY) { 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err=U_ILLEGAL_ARGUMENT_ERROR; /* bad name */ 67185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->locale[0]=0; 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest++=c; 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dest=0; 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(uprv_strncmp(inName, "version=", 8)==0) { 67985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* copy the version option value into bits 3..0 of pPieces->options */ 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName+=8; 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c=*inName; 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c==0) { 68385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=(pPieces->options&=~UCNV_OPTION_VERSION); 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if((uint8_t)(c-'0')<10) { 68685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=pPieces->options=(pPieces->options&~UCNV_OPTION_VERSION)|(uint32_t)(c-'0'); 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++inName; 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(uprv_strncmp(inName, "swaplfnl", 8)==0) { 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inName+=8; 69185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options=(pPieces->options|=UCNV_OPTION_SWAP_LFNL); 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* add processing for new options here with another } else if(uprv_strncmp(inName, "option-name=", XX)==0) { */ 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* ignore any other options until we define some */ 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(((c = *inName++) != 0) && (c != UCNV_OPTION_SEP_CHAR)) { 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(c==0) { 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Logic determines if the converter is Algorithmic AND/OR cached 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *depending on that: 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -we either go to get data from disk and cache it (Data=TRUE, Cached=False) 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -Get it from a Hashtable (Data=X, Cached=TRUE) 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -Call dataConverter initializer (Data=TRUE, Cached=TRUE) 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -Call AlgorithmicConverter initializer (Data=FALSE, Cached=TRUE) 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverterSharedData * 71285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houcnv_loadSharedData(const char *converterName, 71385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces *pPieces, 71485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs *pArgs, 71585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode * err) { 71685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 71785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs; 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData = NULL; 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode internalErrorCode = U_ZERO_ERROR; 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mayContainOption = TRUE; 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool checkForAlgorithmic = TRUE; 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err)) { 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(pPieces == NULL) { 72885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(pArgs != NULL) { 72985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 73085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Bad: We may set pArgs pointers to stackPieces fields 73185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * which will be invalid after this function returns. 73285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 73385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *err = U_INTERNAL_PROGRAM_ERROR; 73485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 73585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 73685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces = &stackPieces; 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 73885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(pArgs == NULL) { 73985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_memset(&stackArgs, 0, sizeof(stackArgs)); 74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.size = (int32_t)sizeof(stackArgs); 74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs = &stackArgs; 74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 74485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->cnvName[0] = 0; 74585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->locale[0] = 0; 74685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pPieces->options = 0; 747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = converterName; 74985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->locale = pPieces->locale; 75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->options = pPieces->options; 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* In case "name" is NULL we want to open the default converter. */ 753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (converterName == NULL) { 75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if U_CHARSET_IS_UTF8 75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = "UTF-8"; 75685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return (UConverterSharedData *)converterData[UCNV_UTF8]; 75785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else 758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Call ucnv_getDefaultName first to query the name from the OS. */ 75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = ucnv_getDefaultName(); 76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (pArgs->name == NULL) { 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_MISSING_RESOURCE_ERROR; 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedConverterData = (UConverterSharedData *)gDefaultAlgorithmicSharedData; 765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru checkForAlgorithmic = FALSE; 766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mayContainOption = gDefaultConverterContainsOption; 767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the default converter name is already canonical */ 76885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else if(UCNV_FAST_IS_UTF8(converterName)) { 771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* fastpath for UTF-8 */ 77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = "UTF-8"; 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UConverterSharedData *)converterData[UCNV_UTF8]; 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* separate the converter name from the options */ 77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(converterName, pPieces, pArgs, err); 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Very bad name used. */ 780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the canonical converter name */ 78485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = ucnv_io_getConverterName(pArgs->name, &mayContainOption, &internalErrorCode); 78585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(internalErrorCode) || pArgs->name == NULL) { 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * set the input name in case the converter was added 788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * without updating the alias table, or when there is no alias table 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->name = pPieces->cnvName; 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* separate the converter name from the options */ 79585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(mayContainOption && pArgs->name != pPieces->cnvName) { 79685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(pArgs->name, pPieces, pArgs, err); 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the shared data for an algorithmic converter, if it is one */ 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (checkForAlgorithmic) { 80185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = (UConverterSharedData *)getAlgorithmicTypeFromName(pArgs->name); 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mySharedConverterData == NULL) 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* it is a data-based converter, get its shared data. */ 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Hold the cnvCacheMutex through the whole process of checking the */ 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* converter data cache, and adding new entries to the cache */ 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* to prevent other threads from modifying the cache during the */ 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* process. */ 81085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->nestedLoads=1; 81185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pArgs->pkg=NULL; 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 81485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = ucnv_load(pArgs, err); 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE (*err) || (mySharedConverterData == NULL)) 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return mySharedConverterData; 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverter * 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createConverter(UConverter *myUConverter, const char *converterName, UErrorCode * err) 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 82885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 82985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) }; 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData; 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN); 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open converter %s", converterName); 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 83785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = ucnv_loadSharedData(converterName, &stackPieces, &stackArgs, err); 83885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 83985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter = ucnv_createConverterFromSharedData( 84085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter, mySharedConverterData, 84185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &stackArgs, 84285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho err); 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*err)) { 84585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_EXIT_PTR_STATUS(myUConverter, *err); 84685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return myUConverter; 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* exit with error */ 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CFUNC UBool 85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Houcnv_canCreateConverter(const char *converterName, UErrorCode *err) { 85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverter myUConverter; 85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 85985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) }; 86085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterSharedData *mySharedConverterData; 86185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 86285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN); 86385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 86485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_SUCCESS(*err)) { 86585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_DATA1(UTRACE_OPEN_CLOSE, "test if can open converter %s", converterName); 86685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 86785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.onlyTestIsLoadable=TRUE; 86885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = ucnv_loadSharedData(converterName, &stackPieces, &stackArgs, err); 86985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_createConverterFromSharedData( 87085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &myUConverter, mySharedConverterData, 87185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &stackArgs, 87285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho err); 87385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_unloadSharedDataIfReady(mySharedConverterData); 87485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 87585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 87685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UTRACE_EXIT_STATUS(*err); 87785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return U_SUCCESS(*err); 87885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 87985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverter * 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createAlgorithmicConverter(UConverter *myUConverter, 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterType type, 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *locale, uint32_t options, 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) { 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv; 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterSharedData *sharedData; 88785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) }; 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_ALGORITHMIC); 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open algorithmic converter type %d", (int32_t)type); 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(type<0 || UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES<=type) { 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR); 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sharedData = converterData[type]; 89985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 90085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Checking whether it's an algorithic converter is okay 90185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho in multithreaded applications because the value never changes. 90285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Don't check referenceCounter for any other value. 90385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 90485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(sharedData == NULL || sharedData->referenceCounter != ~0) { 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* not a valid type, or not an algorithmic converter */ 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_ILLEGAL_ARGUMENT_ERROR; 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR); 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 91185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.name = ""; 91285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.options = options; 91385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.locale=locale; 91485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho cnv = ucnv_createConverterFromSharedData( 91585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter, (UConverterSharedData *)sharedData, 91685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho &stackArgs, err); 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(cnv, *err); 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return cnv; 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverter* 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createConverterFromPackage(const char *packageName, const char *converterName, UErrorCode * err) 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *myUConverter; 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData; 92785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 92885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) }; 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_PACKAGE); 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) { 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA2(UTRACE_OPEN_CLOSE, "open converter %s from package %s", converterName, packageName); 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* first, get the options out of the converterName string */ 94085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.cnvName[0] = 0; 94185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.locale[0] = 0; 94285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.options = 0; 94385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(converterName, &stackPieces, &stackArgs, err); 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Very bad name used. */ 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 94985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.nestedLoads=1; 95085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.pkg=packageName; 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* open the data, unflatten the shared structure */ 95385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData = createConverterFromFile(&stackArgs, err); 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* create the actual converter */ 96185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter = ucnv_createConverterFromSharedData(NULL, mySharedConverterData, &stackArgs, err); 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*err)) { 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(myUConverter); 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_STATUS(*err); 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(myUConverter, *err); 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myUConverter; 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUConverter* 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_createConverterFromSharedData(UConverter *myUConverter, 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedConverterData, 97785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs *pArgs, 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *err) 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool isCopyLocal; 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 98285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_FAILURE(*err)) { 98385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_unloadSharedDataIfReady(mySharedConverterData); 98485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return myUConverter; 98585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(myUConverter == NULL) 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myUConverter = (UConverter *) uprv_malloc (sizeof (UConverter)); 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(myUConverter == NULL) 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_MEMORY_ALLOCATION_ERROR; 99285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ucnv_unloadSharedDataIfReady(mySharedConverterData); 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru isCopyLocal = FALSE; 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru isCopyLocal = TRUE; 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* initialize the converter */ 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(myUConverter, 0, sizeof(UConverter)); 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myUConverter->isCopyLocal = isCopyLocal; 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*myUConverter->isExtraLocal = FALSE;*/ /* Set by the memset call */ 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myUConverter->sharedData = mySharedConverterData; 100585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->options = pArgs->options; 100685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(!pArgs->onlyTestIsLoadable) { 100785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->preFromUFirstCP = U_SENTINEL; 100885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->fromCharErrorBehaviour = UCNV_TO_U_DEFAULT_CALLBACK; 100985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->fromUCharErrorBehaviour = UCNV_FROM_U_DEFAULT_CALLBACK; 101085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->toUnicodeStatus = mySharedConverterData->toUnicodeStatus; 101185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->maxBytesPerUChar = mySharedConverterData->staticData->maxBytesPerChar; 101285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->subChar1 = mySharedConverterData->staticData->subChar1; 101385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->subCharLen = mySharedConverterData->staticData->subCharLen; 101485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->subChars = (uint8_t *)myUConverter->subUChars; 101585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_memcpy(myUConverter->subChars, mySharedConverterData->staticData->subChar, myUConverter->subCharLen); 101685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho myUConverter->toUCallbackReason = UCNV_ILLEGAL; /* default reason to invoke (*fromCharErrorBehaviour) */ 101785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mySharedConverterData->impl->open != NULL) { 102085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho mySharedConverterData->impl->open(myUConverter, pArgs, err); 102185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_FAILURE(*err) && !pArgs->onlyTestIsLoadable) { 102285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* don't ucnv_close() if onlyTestIsLoadable because not fully initialized */ 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(myUConverter); 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myUConverter; 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*Frees all shared immutable objects that aren't referred to (reference count = 0) 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_flushCache () 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterSharedData *mySharedData = NULL; 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t pos; 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t tableDeletedNum = 0; 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UHashElement *e; 104027f654740f2a26ad62a5c155af9199af9e69b889claireho /*UErrorCode status = U_ILLEGAL_ARGUMENT_ERROR;*/ 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i, remaining; 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCNV_FLUSH_CACHE); 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Close the default converter without creating a new one so that everything will be flushed. */ 104627f654740f2a26ad62a5c155af9199af9e69b889claireho u_flushDefaultConverter(); 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*if shared data hasn't even been lazy evaluated yet 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return 0 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) { 1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE((int32_t)0); 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*creates an enumeration to iterate through every element in the 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * table 1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Synchronization: holding cnvCacheMutex will prevent any other thread from 1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * accessing or modifying the hash table during the iteration. 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The reference count of an entry may be decremented by 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ucnv_close while the iteration is in process, but this is 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * benign. It can't be incremented (in ucnv_createConverter()) 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * because the sequence of looking up in the cache + incrementing 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is protected by cnvCacheMutex. 1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * double loop: A delta/extension-only converter has a pointer to its base table's 1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * shared data; the first iteration of the outer loop may see the delta converter 1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * before the base converter, and unloading the delta converter may get the base 1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * converter's reference counter down to 0. 1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i = 0; 1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remaining = 0; 1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = -1; 1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((e = uhash_nextElement (SHARED_DATA_HASHTABLE, &pos)) != NULL) 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedData = (UConverterSharedData *) e->value.pointer; 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*deletes only if reference counter == 0 */ 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mySharedData->referenceCounter == 0) 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tableDeletedNum++; 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_DEBUG_LOG("del",mySharedData->staticData->name,mySharedData); 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uhash_removeElement(SHARED_DATA_HASHTABLE, e); 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mySharedData->sharedDataCached = FALSE; 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_deleteSharedConverterData (mySharedData); 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++remaining; 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(++i == 1 && remaining > 0); 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_DATA1(UTRACE_INFO, "ucnv_flushCache() exits with %d converters remaining", remaining); 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UTRACE_EXIT_VALUE(tableDeletedNum); 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tableDeletedNum; 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* available converters list --------------------------------------------------- */ 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool haveAvailableConverterList(UErrorCode *pErrorCode) { 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int needInit; 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UMTX_CHECK(&cnvCacheMutex, (gAvailableConverters == NULL), needInit); 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (needInit) { 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter tempConverter; 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UEnumeration *allConvEnum = NULL; 1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t idx; 1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t localConverterCount; 1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t allConverterCount; 1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode localStatus; 1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *converterName; 1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char **localConverterList; 1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru allConvEnum = ucnv_openAllNames(pErrorCode); 1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru allConverterCount = uenum_count(allConvEnum, pErrorCode); 1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*pErrorCode)) { 1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* We can't have more than "*converterTable" converters to open */ 1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverterList = (const char **) uprv_malloc(allConverterCount * sizeof(char*)); 1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!localConverterList) { 1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Open the default converter to make sure that it has first dibs in the hash table. */ 1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localStatus = U_ZERO_ERROR; 1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(ucnv_createConverter(&tempConverter, NULL, &localStatus)); 1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverterCount = 0; 1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (idx = 0; idx < allConverterCount; idx++) { 1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localStatus = U_ZERO_ERROR; 1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterName = uenum_next(allConvEnum, NULL, &localStatus); 114185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (ucnv_canCreateConverter(converterName, &localStatus)) { 1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localConverterList[localConverterCount++] = converterName; 1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uenum_close(allConvEnum); 1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (gAvailableConverters == NULL) { 1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gAvailableConverterCount = localConverterCount; 115085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho gAvailableConverters = localConverterList; 1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup); 1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free((char **)localConverterList); 1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC uint16_t 1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_bld_countAvailableConverters(UErrorCode *pErrorCode) { 1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAvailableConverterList(pErrorCode)) { 1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gAvailableConverterCount; 1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC const char * 1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_bld_getAvailableConverter(uint16_t n, UErrorCode *pErrorCode) { 1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAvailableConverterList(pErrorCode)) { 1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n < gAvailableConverterCount) { 1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gAvailableConverters[n]; 1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; 1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* default converter name --------------------------------------------------- */ 1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 118285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCopy the canonical converter name. 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getDefaultName must be thread safe, which can call this function. 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setDefaultName calls this function and it doesn't have to be 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruthread safe because there is no reliable/safe way to reset the 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconverter in use in all threads. If you did reset the converter, you 1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruwould not be sure that retrieving a default converter for one string 1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruwould be the same type of default converter for a successive string. 1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSince the name is a returned via ucnv_getDefaultName without copying, 1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruyou shouldn't be modifying or deleting the string from a separate thread. 1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic U_INLINE void 1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruinternalSetName(const char *name, UErrorCode *status) { 119785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterNamePieces stackPieces; 119885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) }; 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length=(int32_t)(uprv_strlen(name)); 1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool containsOption = (UBool)(uprv_strchr(name, UCNV_OPTION_SEP_CHAR) != NULL); 1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterSharedData *algorithmicSharedData; 1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackArgs.name = name; 1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(containsOption) { 120585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.cnvName[0] = 0; 120685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.locale[0] = 0; 120785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho stackPieces.options = 0; 120885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parseConverterOptions(name, &stackPieces, &stackArgs, status); 120985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_FAILURE(*status)) { 121085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 121185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 121385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho algorithmicSharedData = getAlgorithmicTypeFromName(stackArgs.name); 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_lock(&cnvCacheMutex); 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultAlgorithmicSharedData = algorithmicSharedData; 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterContainsOption = containsOption; 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(gDefaultConverterNameBuffer, name, length); 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterNameBuffer[length]=0; 122185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 122285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* gDefaultConverterName MUST be the last global var set by this function. */ 122385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* It is the variable checked in ucnv_getDefaultName() to see if initialization is required. */ 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterName = gDefaultConverterNameBuffer; 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup); 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru umtx_unlock(&cnvCacheMutex); 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 123085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In order to be really thread-safe, the get function would have to take 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a buffer parameter and copy the current string inside a mutex block. 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This implementation only tries to be really thread-safe while 1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * setting the name. 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It assumes that setting a pointer is atomic. 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getDefaultName() { 124285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if U_CHARSET_IS_UTF8 124385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return "UTF-8"; 124485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* local variable to be thread-safe */ 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name; 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Multiple calls to ucnv_getDefaultName must be thread safe, 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru but ucnv_setDefaultName is not thread safe. 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UMTX_CHECK(&cnvCacheMutex, gDefaultConverterName, name); 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(name==NULL) { 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv = NULL; 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = uprv_getDefaultCodepage(); 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the name is there, test it out and get the canonical name with options */ 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(name != NULL) { 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv = ucnv_open(name, &errorCode); 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(errorCode) && cnv != NULL) { 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = ucnv_getName(cnv, &errorCode); 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(name == NULL || name[0] == 0 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || U_FAILURE(errorCode) || cnv == NULL 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || uprv_strlen(name)>=sizeof(gDefaultConverterNameBuffer)) 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Panic time, let's use a fallback. */ 1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if (U_CHARSET_FAMILY == U_ASCII_FAMILY) 1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = "US-ASCII"; 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is no 'algorithmic' converter for EBCDIC */ 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#elif defined(OS390) 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = "ibm-1047_P100-1995" UCNV_SWAP_LFNL_OPTION_STRING; 1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = "ibm-37_P100-1995"; 1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru internalSetName(name, &errorCode); 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The close may make the current name go away. */ 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(cnv); 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 128985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThis function is not thread safe, and it can't be thread safe. 1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSee internalSetName or the API reference for details. 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_setDefaultName(const char *converterName) { 129885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !U_CHARSET_IS_UTF8 1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(converterName==NULL) { 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset to the default codepage */ 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gDefaultConverterName=NULL; 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *cnv = NULL; 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *name = NULL; 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if the name is there, test it out and get the canonical name with options */ 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnv = ucnv_open(converterName, &errorCode); 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(errorCode) && cnv != NULL) { 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name = ucnv_getName(cnv, &errorCode); 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(errorCode) && name!=NULL) { 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru internalSetName(name, &errorCode); 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else this converter is bad to use. Don't change it to a bad value. */ 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The close may make the current name go away. */ 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_close(cnv); 132027f654740f2a26ad62a5c155af9199af9e69b889claireho 132127f654740f2a26ad62a5c155af9199af9e69b889claireho /* reset the converter cache */ 132227f654740f2a26ad62a5c155af9199af9e69b889claireho u_flushDefaultConverter(); 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 132485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* data swapping ------------------------------------------------------------ */ 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* most of this might belong more properly into ucnvmbcs.c, but that is so large */ 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_LEGACY_CONVERSION 1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_swap(const UDataSwapper *ds, 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataInfo *pInfo; 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t headerSize; 1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint8_t *inBytes; 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t *outBytes; 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t offset, count, staticDataSize; 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t size; 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UConverterStaticData *inStaticData; 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverterStaticData *outStaticData; 1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const _MBCSHeader *inMBCSHeader; 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _MBCSHeader *outMBCSHeader; 1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru _MBCSHeader mbcsHeader; 1352c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru uint32_t mbcsHeaderLength; 1353c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru UBool noFromU=FALSE; 1354c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t outputType; 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxFastUChar, mbcsIndexLength; 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const int32_t *inExtIndexes; 1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t extOffset; 1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check data format and format version */ 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!( 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x63 && /* dataFormat="cnvt" */ 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x6e && 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x76 && 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x74 && 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==6 && 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[1]>=2 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru )) { 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-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", 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0], pInfo->formatVersion[1]); 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes=(const uint8_t *)inData+headerSize; 1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes=(uint8_t *)outData+headerSize; 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the initial UConverterStaticData structure after the UDataInfo header */ 1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inStaticData=(const UConverterStaticData *)inBytes; 1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outStaticData=(UConverterStaticData *)outBytes; 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<0) { 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru staticDataSize=ds->readUInt32(inStaticData->structSize); 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-=headerSize; 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( length<sizeof(UConverterStaticData) || 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uint32_t)length<(staticDataSize=ds->readUInt32(inStaticData->structSize)) 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after header) for an ICU .cnv conversion table\n", 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the static data */ 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inStaticData!=outStaticData) { 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outStaticData, inStaticData, staticDataSize); 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, &inStaticData->structSize, 4, 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &outStaticData->structSize, pErrorCode); 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, &inStaticData->codepage, 4, 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &outStaticData->codepage, pErrorCode); 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapInvChars(ds, inStaticData->name, (int32_t)uprv_strlen(inStaticData->name), 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outStaticData->name, pErrorCode); 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): error swapping converter name\n"); 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes+=staticDataSize; 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+=staticDataSize; 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-=(int32_t)staticDataSize; 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check for supported conversionType values */ 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inStaticData->conversionType==UCNV_MBCS) { 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap MBCS data */ 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inMBCSHeader=(const _MBCSHeader *)inBytes; 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outMBCSHeader=(_MBCSHeader *)outBytes; 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(0<=length && length<sizeof(_MBCSHeader)) { 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table\n", 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1444c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if(inMBCSHeader->version[0]==4 && inMBCSHeader->version[1]>=1) { 1445c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru mbcsHeaderLength=MBCS_HEADER_V4_LENGTH; 1446c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } else if(inMBCSHeader->version[0]==5 && inMBCSHeader->version[1]>=3 && 1447c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ((mbcsHeader.options=ds->readUInt32(inMBCSHeader->options))& 1448c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru MBCS_OPT_UNKNOWN_INCOMPATIBLE_MASK)==0 1449c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ) { 1450c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru mbcsHeaderLength=mbcsHeader.options&MBCS_OPT_LENGTH_MASK; 1451c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru noFromU=(UBool)((mbcsHeader.options&MBCS_OPT_NO_FROM_U)!=0); 1452c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } else { 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unsupported _MBCSHeader.version %d.%d\n", 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inMBCSHeader->version[0], inMBCSHeader->version[1]); 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(mbcsHeader.version, inMBCSHeader->version, 4); 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.countStates= ds->readUInt32(inMBCSHeader->countStates); 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.countToUFallbacks= ds->readUInt32(inMBCSHeader->countToUFallbacks); 1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.offsetToUCodeUnits= ds->readUInt32(inMBCSHeader->offsetToUCodeUnits); 1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.offsetFromUTable= ds->readUInt32(inMBCSHeader->offsetFromUTable); 1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.offsetFromUBytes= ds->readUInt32(inMBCSHeader->offsetFromUBytes); 1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.flags= ds->readUInt32(inMBCSHeader->flags); 1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.fromUBytesLength= ds->readUInt32(inMBCSHeader->fromUBytesLength); 1467c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /* mbcsHeader.options have been read above */ 1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru extOffset=(int32_t)(mbcsHeader.flags>>8); 1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outputType=(uint8_t)mbcsHeader.flags; 1471c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if(noFromU && outputType==MBCS_OUTPUT_1) { 1472c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unsupported combination of makeconv --small with SBCS\n"); 1473c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1474c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru return 0; 1475c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* make sure that the output type is known */ 1478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(outputType) { 1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_1: 1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2: 1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_3: 1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_4: 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_3_EUC: 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_4_EUC: 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2_SISO: 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_EXT_ONLY: 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* OK */ 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unsupported MBCS output type 0x%x\n", 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outputType); 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* calculate the length of the MBCS data */ 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * utf8Friendly MBCS files (mbcsHeader.version 4.3) 1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * contain an additional mbcsIndex table: 1501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * uint16_t[(maxFastUChar+1)>>6]; 1502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * where maxFastUChar=((mbcsHeader.version[2]<<8)|0xff). 1503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxFastUChar=0; 1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsIndexLength=0; 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( outputType!=MBCS_OUTPUT_EXT_ONLY && outputType!=MBCS_OUTPUT_1 && 1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsHeader.version[1]>=3 && (maxFastUChar=mbcsHeader.version[2])!=0 1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxFastUChar=(maxFastUChar<<8)|0xff; 1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mbcsIndexLength=((maxFastUChar+1)>>6)*2; /* number of bytes */ 1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(extOffset==0) { 1514c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru size=(int32_t)(mbcsHeader.offsetFromUBytes+mbcsIndexLength); 1515c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru if(!noFromU) { 1516c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru size+=(int32_t)mbcsHeader.fromUBytesLength; 1517c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru } 1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* avoid compiler warnings - not otherwise necessary, and the value does not matter */ 1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inExtIndexes=NULL; 1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is extension data after the base data, see ucnv_ext.h */ 1523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0 && length<(extOffset+UCNV_EXT_INDEXES_MIN_LENGTH*4)) { 1524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table with extension data\n", 1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inExtIndexes=(const int32_t *)(inBytes+extOffset); 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size=extOffset+udata_readInt32(ds, inExtIndexes[UCNV_EXT_SIZE]); 1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<size) { 1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table\n", 1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the data for inaccessible bytes */ 1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inBytes!=outBytes) { 1544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outBytes, inBytes, size); 1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1547c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru /* swap the MBCSHeader, except for the version field */ 1548c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count=mbcsHeaderLength*4; 1549c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapArray32(ds, &inMBCSHeader->countStates, count-4, 1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &outMBCSHeader->countStates, pErrorCode); 1551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(outputType==MBCS_OUTPUT_EXT_ONLY) { 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * extension-only file, 1555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * contains a base name instead of normal base table data 1556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the base name, between the header and the extension data */ 1559c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru const char *inBaseName=(const char *)inBytes+count; 1560c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru char *outBaseName=(char *)outBytes+count; 1561c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapInvChars(ds, inBaseName, (int32_t)uprv_strlen(inBaseName), 1562c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru outBaseName, pErrorCode); 1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* normal file with base table data */ 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the state table, 1kB per state */ 1567c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru offset=count; 1568c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count=mbcsHeader.countStates*1024; 1569c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1570c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru outBytes+offset, pErrorCode); 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the toUFallbacks[] */ 1573c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru offset+=count; 1574c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count=mbcsHeader.countToUFallbacks*8; 1575c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the unicodeCodeUnits[] */ 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=mbcsHeader.offsetToUCodeUnits; 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=mbcsHeader.offsetFromUTable-offset; 1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* offset to the stage 1 table, independent of the outputType */ 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=mbcsHeader.offsetFromUTable; 1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(outputType==MBCS_OUTPUT_1) { 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* SBCS: swap the fromU tables, all 16 bits wide */ 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=(mbcsHeader.offsetFromUBytes-offset)+mbcsHeader.fromUBytesLength; 1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* otherwise: swap the stage tables separately */ 1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* stage 1 table: uint16_t[0x440 or 0x40] */ 1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inStaticData->unicodeMask&UCNV_HAS_SUPPLEMENTARY) { 1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=0x440*2; /* for all of Unicode */ 1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=0x40*2; /* only BMP */ 1600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* stage 2 table: uint32_t[] */ 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset+=count; 1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=mbcsHeader.offsetFromUBytes-offset; 1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* stage 3/result bytes: sometimes uint16_t[] or uint32_t[] */ 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=mbcsHeader.offsetFromUBytes; 1612c0f3e2506e4cc62ff8c220fe72849728e9d6cecfJean-Baptiste Queru count= noFromU ? 0 : mbcsHeader.fromUBytesLength; 1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(outputType) { 1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2: 1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_3_EUC: 1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_2_SISO: 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MBCS_OUTPUT_4: 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, (int32_t)count, 1622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* just uint8_t[], nothing to swap */ 1626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mbcsIndexLength!=0) { 1630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset+=count; 1631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=mbcsIndexLength; 1632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, (int32_t)count, 1633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+offset, pErrorCode); 1634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(extOffset!=0) { 1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the extension data */ 1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes+=extOffset; 1641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+=extOffset; 1642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap toUTable[] */ 1644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_INDEX]); 1645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_LENGTH]); 1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, length*4, outBytes+offset, pErrorCode); 1647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap toUUChars[] */ 1649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_UCHARS_INDEX]); 1650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_TO_U_UCHARS_LENGTH]); 1651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUTableUChars[] */ 1654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_UCHARS_INDEX]); 1655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_LENGTH]); 1656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUTableValues[] */ 1659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_VALUES_INDEX]); 1660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* same length as for fromUTableUChars[] */ 1661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, length*4, outBytes+offset, pErrorCode); 1662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no need to swap fromUBytes[] */ 1664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUStage12[] */ 1666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_12_INDEX]); 1667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_12_LENGTH]); 1668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUStage3[] */ 1671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3_INDEX]); 1672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3_LENGTH]); 1673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, length*2, outBytes+offset, pErrorCode); 1674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap fromUStage3b[] */ 1676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3B_INDEX]); 1677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_FROM_U_STAGE_3B_LENGTH]); 1678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, length*4, outBytes+offset, pErrorCode); 1679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap indexes[] */ 1681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_readInt32(ds, inExtIndexes[UCNV_EXT_INDEXES_LENGTH]); 1682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes, length*4, outBytes, pErrorCode); 1683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swap(): unknown conversionType=%d!=UCNV_MBCS\n", 1687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inStaticData->conversionType); 1688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+(int32_t)staticDataSize+size; 1693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */ 1696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1698