1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 459d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1999-2013, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 10103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* ucnv_io.cpp: 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* initializes global variables and defines functions pertaining to converter 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* name resolution aspect of the conversion code. 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* new implementation: 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created on: 1999nov22 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by: Markus W. Scherer 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Use the binary cnvalias.icu (created from convrtrs.txt) to work 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* with aliases for converter names. 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11/22/1999 markus Created 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 06/28/2002 grhoten Major overhaul of the converter alias design. 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Now an alias can map to different converters 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* depending on the specified standard. 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_CONVERSION 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uarrsort.h" 3959d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h" 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "udataswp.h" 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_io.h" 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uenumimp.h" 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucln_cmn.h" 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Format of cnvalias.icu ----------------------------------------------------- 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * cnvalias.icu is a binary, memory-mappable form of convrtrs.txt. 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This binary form contains several tables. All indexes are to uint16_t 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * units, and not to the bytes (uint8_t units). Addressing everything on 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 16-bit boundaries allows us to store more information with small index 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * numbers, which are also 16-bit in size. The majority of the table (except 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the string table) are 16-bit numbers. 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * First there is the size of the Table of Contents (TOC). The TOC 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * entries contain the size of each section. In order to find the offset 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * you just need to sum up the previous offsets. 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The TOC length and entries are an array of uint32_t values. 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The first section after the TOC starts immediately after the TOC. 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1) This section contains a list of converters. This list contains indexes 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * into the string table for the converter name. The index of this list is 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * also used by other sections, which are mentioned later on. 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This list is not sorted. 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2) This section contains a list of tags. This list contains indexes 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * into the string table for the tag name. The index of this list is 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * also used by other sections, which are mentioned later on. 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This list is in priority order of standards. 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 3) This section contains a list of sorted unique aliases. This 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * list contains indexes into the string table for the alias name. The 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * index of this list is also used by other sections, like the 4th section. 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The index for the 3rd and 4th section is used to get the 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * alias -> converter name mapping. Section 3 and 4 form a two column table. 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Some of the most significant bits of each index may contain other 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * information (see findConverter for details). 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 4) This section contains a list of mapped converter names. Consider this 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * as a table that maps the 3rd section to the 1st section. This list contains 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * indexes into the 1st section. The index of this list is the same index in 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the 3rd section. There is also some extra information in the high bits of 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * each converter index in this table. Currently it's only used to say that 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * an alias mapped to this converter is ambiguous. See UCNV_CONVERTER_INDEX_MASK 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and UCNV_AMBIGUOUS_ALIAS_MAP_BIT for more information. This section is 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the predigested form of the 5th section so that an alias lookup can be fast. 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 5) This section contains a 2D array with indexes to the 6th section. This 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * section is the full form of all alias mappings. The column index is the 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * index into the converter list (column header). The row index is the index 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to tag list (row header). This 2D array is the top part a 3D array. The 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * third dimension is in the 6th section. 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 6) This is blob of variable length arrays. Each array starts with a size, 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and is followed by indexes to alias names in the string table. This is 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the third dimension to the section 5. No other section should be referencing 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * this section. 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 7) Starting in ICU 3.6, this can be a UConverterAliasOptions struct. Its 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * presence indicates that a section 9 exists. UConverterAliasOptions specifies 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * what type of string normalization is used among other potential things in the 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * future. 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 8) This is the string table. All strings are indexed on an even address. 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * There are two reasons for this. First many chip architectures locate strings 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * faster on even address boundaries. Second, since all indexes are 16-bit 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * numbers, this string table can be 128KB in size instead of 64KB when we 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * only have strings starting on an even address. 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 9) When present this is a set of prenormalized strings from section 8. This 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * table contains normalized strings with the dashes and spaces stripped out, 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and all strings lowercased. In the future, the options in section 7 may state 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * other types of normalization. 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Here is the concept of section 5 and 6. It's a 3D cube. Each tag 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * has a unique alias among all converters. That same alias can 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * be mentioned in other standards on different converters, 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * but only one alias per tag can be unique. 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Converter Names (Usually in TR22 form) 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -------------------------------------------. 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * T / /| 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a / / | 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * g / / | 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s / / | 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * / / | 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ------------------------------------------/ | 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A | | | 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * l | | | 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * i | | / 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a | | / 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s | | / 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * e | | / 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s | |/ 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ------------------------------------------- 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Here is what it really looks like. It's like swiss cheese. 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * There are holes. Some converters aren't recognized by 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a standard, or they are really old converters that the 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * standard doesn't recognize anymore. 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Converter Names (Usually in TR22 form) 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * -------------------------------------------. 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * T /##########################################/| 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a / # # /# 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * g / # ## ## ### # ### ### ### #/ 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s / # ##### #### ## ## #/# 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * / ### # # ## # # # ### # # #/## 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ------------------------------------------/# # 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A |### # # ## # # # ### # # #|# # 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * l |# # # # # ## # #|# # 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * i |# # # # # # #|# 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a |# #|# 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s | #|# 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * e 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * s 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Used by the UEnumeration API 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct UAliasContext { 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset; 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listIdx; 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} UAliasContext; 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char DATA_NAME[] = "cnvalias"; 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char DATA_TYPE[] = "icu"; 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UDataMemory *gAliasData=NULL; 17659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gAliasDataInitOnce = U_INITONCE_INITIALIZER; 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tocLengthIndex=0, 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converterListIndex=1, 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tagListIndex=2, 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru aliasListIndex=3, 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru untaggedConvArrayIndex=4, 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru taggedAliasArrayIndex=5, 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru taggedAliasListsIndex=6, 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tableOptionsIndex=7, 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru stringTableIndex=8, 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru normalizedStringTableIndex=9, 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsetsCount, /* length of the swapper's temporary offsets[] */ 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minTocLength=8 /* min. tocLength in the file, does not count the tocLengthIndex! */ 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UConverterAliasOptions defaultTableOptions = { 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCNV_IO_UNNORMALIZED, 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0 /* containsCnvOptionInfo */ 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UConverterAlias gMainTable; 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define GET_STRING(idx) (const char *)(gMainTable.stringTable + (idx)) 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define GET_NORMALIZED_STRING(idx) (const char *)(gMainTable.normalizedStringTable + (idx)) 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV 203103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusisAcceptable(void * /*context*/, 204103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const char * /*type*/, const char * /*name*/, 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataInfo *pInfo) { 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UBool)( 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->size>=20 && 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x43 && /* dataFormat="CvAl" */ 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x76 && 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x41 && 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x6c && 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==3); 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV ucnv_io_cleanup(void) 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (gAliasData) { 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_close(gAliasData); 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru gAliasData = NULL; 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 22359d709d503bab6e2b61931737e662dd293b40578ccornelius gAliasDataInitOnce.reset(); 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(&gMainTable, 0, sizeof(gMainTable)); 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; /* Everything was cleaned up */ 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initAliasData(UErrorCode &errCode) { 23159d709d503bab6e2b61931737e662dd293b40578ccornelius UDataMemory *data; 23259d709d503bab6e2b61931737e662dd293b40578ccornelius const uint16_t *table; 23359d709d503bab6e2b61931737e662dd293b40578ccornelius const uint32_t *sectionSizes; 23459d709d503bab6e2b61931737e662dd293b40578ccornelius uint32_t tableStart; 23559d709d503bab6e2b61931737e662dd293b40578ccornelius uint32_t currOffset; 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23759d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23959d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gAliasData == NULL); 24059d709d503bab6e2b61931737e662dd293b40578ccornelius data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &errCode); 24159d709d503bab6e2b61931737e662dd293b40578ccornelius if(U_FAILURE(errCode)) { 24259d709d503bab6e2b61931737e662dd293b40578ccornelius return; 24359d709d503bab6e2b61931737e662dd293b40578ccornelius } 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24559d709d503bab6e2b61931737e662dd293b40578ccornelius sectionSizes = (const uint32_t *)udata_getMemory(data); 24659d709d503bab6e2b61931737e662dd293b40578ccornelius table = (const uint16_t *)sectionSizes; 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24859d709d503bab6e2b61931737e662dd293b40578ccornelius tableStart = sectionSizes[0]; 24959d709d503bab6e2b61931737e662dd293b40578ccornelius if (tableStart < minTocLength) { 25059d709d503bab6e2b61931737e662dd293b40578ccornelius errCode = U_INVALID_FORMAT_ERROR; 25159d709d503bab6e2b61931737e662dd293b40578ccornelius udata_close(data); 25259d709d503bab6e2b61931737e662dd293b40578ccornelius return; 25359d709d503bab6e2b61931737e662dd293b40578ccornelius } 25459d709d503bab6e2b61931737e662dd293b40578ccornelius gAliasData = data; 25559d709d503bab6e2b61931737e662dd293b40578ccornelius 25659d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.converterListSize = sectionSizes[1]; 25759d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.tagListSize = sectionSizes[2]; 25859d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.aliasListSize = sectionSizes[3]; 25959d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.untaggedConvArraySize = sectionSizes[4]; 26059d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.taggedAliasArraySize = sectionSizes[5]; 26159d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.taggedAliasListsSize = sectionSizes[6]; 26259d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.optionTableSize = sectionSizes[7]; 26359d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.stringTableSize = sectionSizes[8]; 26459d709d503bab6e2b61931737e662dd293b40578ccornelius 26559d709d503bab6e2b61931737e662dd293b40578ccornelius if (tableStart > 8) { 26659d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.normalizedStringTableSize = sectionSizes[9]; 26759d709d503bab6e2b61931737e662dd293b40578ccornelius } 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26959d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t)); 27059d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.converterList = table + currOffset; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27259d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.converterListSize; 27359d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.tagList = table + currOffset; 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27559d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.tagListSize; 27659d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.aliasList = table + currOffset; 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27859d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.aliasListSize; 27959d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.untaggedConvArray = table + currOffset; 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28159d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.untaggedConvArraySize; 28259d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.taggedAliasArray = table + currOffset; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28459d709d503bab6e2b61931737e662dd293b40578ccornelius /* aliasLists is a 1's based array, but it has a padding character */ 28559d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.taggedAliasArraySize; 28659d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.taggedAliasLists = table + currOffset; 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28859d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.taggedAliasListsSize; 28959d709d503bab6e2b61931737e662dd293b40578ccornelius if (gMainTable.optionTableSize > 0 29059d709d503bab6e2b61931737e662dd293b40578ccornelius && ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT) 29159d709d503bab6e2b61931737e662dd293b40578ccornelius { 29259d709d503bab6e2b61931737e662dd293b40578ccornelius /* Faster table */ 29359d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset); 29459d709d503bab6e2b61931737e662dd293b40578ccornelius } 29559d709d503bab6e2b61931737e662dd293b40578ccornelius else { 29659d709d503bab6e2b61931737e662dd293b40578ccornelius /* Smaller table, or I can't handle this normalization mode! 29759d709d503bab6e2b61931737e662dd293b40578ccornelius Use the original slower table lookup. */ 29859d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.optionTable = &defaultTableOptions; 29959d709d503bab6e2b61931737e662dd293b40578ccornelius } 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30159d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.optionTableSize; 30259d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.stringTable = table + currOffset; 30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 30459d709d503bab6e2b61931737e662dd293b40578ccornelius currOffset += gMainTable.stringTableSize; 30559d709d503bab6e2b61931737e662dd293b40578ccornelius gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED) 30659d709d503bab6e2b61931737e662dd293b40578ccornelius ? gMainTable.stringTable : (table + currOffset)); 30759d709d503bab6e2b61931737e662dd293b40578ccornelius} 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UBool 31159d709d503bab6e2b61931737e662dd293b40578ccorneliushaveAliasData(UErrorCode *pErrorCode) { 31259d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gAliasDataInitOnce, &initAliasData, *pErrorCode); 31359d709d503bab6e2b61931737e662dd293b40578ccornelius return U_SUCCESS(*pErrorCode); 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 316103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline UBool 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruisAlias(const char *alias, UErrorCode *pErrorCode) { 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(alias==NULL) { 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UBool)(*alias!=0); 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint32_t getTagNumber(const char *tagname) { 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (gMainTable.tagList) { 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t tagNum; 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (tagNum = 0; tagNum < gMainTable.tagListSize; tagNum++) { 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!uprv_stricmp(GET_STRING(gMainTable.tagList[tagNum]), tagname)) { 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tagNum; 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UINT32_MAX; 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* character types relevant for ucnv_compareNames() */ 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 34059d709d503bab6e2b61931737e662dd293b40578ccornelius UIGNORE, 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ZERO, 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NONZERO, 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MINLETTER /* any values from here on are lowercase letter mappings */ 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* character types for ASCII 00..7F */ 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const uint8_t asciiTypes[128] = { 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0, 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0, 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 35859d709d503bab6e2b61931737e662dd293b40578ccornelius#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)UIGNORE) 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* character types for EBCDIC 80..FF */ 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const uint8_t ebcdicTypes[128] = { 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0, 0, 0, 0, 0, 0, 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0, 0, 0, 0, 0, 0, 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0, 0, 0, 0, 0, 0, 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0, 0, 0, 0, 0, 0, 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0, 0, 0, 0, 0, 0, 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0, 0, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0, 0, 0, 0, 0, 0, 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 37259d709d503bab6e2b61931737e662dd293b40578ccornelius#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)UIGNORE) 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_CHARSET_FAMILY==U_ASCII_FAMILY 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define GET_CHAR_TYPE(c) GET_ASCII_TYPE(c) 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define GET_CHAR_TYPE(c) GET_EBCDIC_TYPE(c) 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# error U_CHARSET_FAMILY is not valid 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* @see ucnv_compareNames */ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC char * U_EXPORT2 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_stripASCIIForCompare(char *dst, const char *name) { 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *dstItr = dst; 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t type, nextType; 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char c1; 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool afterDigit = FALSE; 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((c1 = *name++) != 0) { 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru type = GET_ASCII_TYPE(c1); 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (type) { 39359d709d503bab6e2b61931737e662dd293b40578ccornelius case UIGNORE: 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit = FALSE; 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore all but letters and digits */ 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ZERO: 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!afterDigit) { 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru nextType = GET_ASCII_TYPE(*name); 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (nextType == ZERO || nextType == NONZERO) { 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore leading zero before another digit */ 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NONZERO: 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit = TRUE; 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c1 = (char)type; /* lowercased letter */ 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit = FALSE; 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dstItr++ = c1; 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dstItr = 0; 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return dst; 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC char * U_EXPORT2 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_stripEBCDICForCompare(char *dst, const char *name) { 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *dstItr = dst; 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t type, nextType; 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char c1; 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool afterDigit = FALSE; 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((c1 = *name++) != 0) { 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru type = GET_EBCDIC_TYPE(c1); 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (type) { 42859d709d503bab6e2b61931737e662dd293b40578ccornelius case UIGNORE: 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit = FALSE; 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore all but letters and digits */ 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ZERO: 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!afterDigit) { 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru nextType = GET_EBCDIC_TYPE(*name); 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (nextType == ZERO || nextType == NONZERO) { 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore leading zero before another digit */ 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NONZERO: 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit = TRUE; 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c1 = (char)type; /* lowercased letter */ 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit = FALSE; 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dstItr++ = c1; 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *dstItr = 0; 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return dst; 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Do a fuzzy compare of two converter/alias names. 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The comparison is case-insensitive, ignores leading zeroes if they are not 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * followed by further digits, and ignores all but letters and digits. 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Thus the strings "UTF-8", "utf_8", "u*T@f08" and "Utf 8" are exactly equivalent. 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * See section 1.4, Charset Alias Matching in Unicode Technical Standard #22 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * at http://www.unicode.org/reports/tr22/ 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This is a symmetrical (commutative) operation; order of arguments 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is insignificant. This is an important property for sorting the 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * list (when the list is preprocessed into binary form) and for 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * performing binary searches on it at run time. 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param name1 a converter name or alias, zero-terminated 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param name2 a converter name or alias, zero-terminated 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return 0 if the names match, or a negative value if the name1 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * lexically precedes name2, or a positive value if the name1 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * lexically follows name2. 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @see ucnv_io_stripForCompare 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int U_EXPORT2 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_compareNames(const char *name1, const char *name2) { 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int rc; 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t type, nextType; 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char c1, c2; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool afterDigit1 = FALSE, afterDigit2 = FALSE; 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;;) { 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((c1 = *name1++) != 0) { 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru type = GET_CHAR_TYPE(c1); 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (type) { 48559d709d503bab6e2b61931737e662dd293b40578ccornelius case UIGNORE: 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit1 = FALSE; 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore all but letters and digits */ 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ZERO: 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!afterDigit1) { 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru nextType = GET_CHAR_TYPE(*name1); 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (nextType == ZERO || nextType == NONZERO) { 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore leading zero before another digit */ 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NONZERO: 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit1 = TRUE; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c1 = (char)type; /* lowercased letter */ 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit1 = FALSE; 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* deliver c1 */ 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((c2 = *name2++) != 0) { 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru type = GET_CHAR_TYPE(c2); 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (type) { 50959d709d503bab6e2b61931737e662dd293b40578ccornelius case UIGNORE: 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit2 = FALSE; 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore all but letters and digits */ 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ZERO: 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!afterDigit2) { 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru nextType = GET_CHAR_TYPE(*name2); 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (nextType == ZERO || nextType == NONZERO) { 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; /* ignore leading zero before another digit */ 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NONZERO: 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit2 = TRUE; 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c2 = (char)type; /* lowercased letter */ 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru afterDigit2 = FALSE; 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* deliver c2 */ 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* If we reach the ends of both strings then they match */ 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((c1|c2)==0) { 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Case-insensitive comparison */ 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc = (int)(unsigned char)c1 - (int)(unsigned char)c2; 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rc != 0) { 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rc; 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * search for an alias 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return the converter number index for gConverterList 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline uint32_t 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerufindConverter(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) { 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t mid, start, limit; 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t lastMid; 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int result; 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int isUnnormalized = (gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED); 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char strippedName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!isUnnormalized) { 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (uprv_strlen(alias) >= UCNV_MAX_CONVERTER_NAME_LENGTH) { 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_BUFFER_OVERFLOW_ERROR; 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UINT32_MAX; 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Lower case and remove ignoreable characters. */ 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_stripForCompare(strippedName, alias); 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias = strippedName; 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do a binary search for the alias */ 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = 0; 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = gMainTable.untaggedConvArraySize; 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = limit; 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastMid = UINT32_MAX; 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;;) { 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = (uint32_t)((start + limit) / 2); 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lastMid == mid) { /* Have we moved? */ 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* We haven't moved, and it wasn't found. */ 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastMid = mid; 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isUnnormalized) { 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = ucnv_compareNames(alias, GET_STRING(gMainTable.aliasList[mid])); 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = uprv_strcmp(alias, GET_NORMALIZED_STRING(gMainTable.aliasList[mid])); 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result < 0) { 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = mid; 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (result > 0) { 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = mid; 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Since the gencnval tool folds duplicates into one entry, 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * this alias in gAliasList is unique, but different standards 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * may map an alias to different converters. 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (gMainTable.untaggedConvArray[mid] & UCNV_AMBIGUOUS_ALIAS_MAP_BIT) { 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_AMBIGUOUS_ALIAS_WARNING; 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* State whether the canonical converter name contains an option. 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This information is contained in this list in order to maintain backward & forward compatibility. */ 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (containsOption) { 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool containsCnvOptionInfo = (UBool)gMainTable.optionTable->containsCnvOptionInfo; 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *containsOption = (UBool)((containsCnvOptionInfo 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru && ((gMainTable.untaggedConvArray[mid] & UCNV_CONTAINS_OPTION_BIT) != 0)) 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || !containsCnvOptionInfo); 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gMainTable.untaggedConvArray[mid] & UCNV_CONVERTER_INDEX_MASK; 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UINT32_MAX; 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Is this alias in this list? 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * alias and listOffset should be non-NULL. 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 617103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline UBool 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruisAliasInList(const char *alias, uint32_t listOffset) { 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset) { 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t currAlias; 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* +1 to skip listCount */ 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (currAlias = 0; currAlias < listCount; currAlias++) { 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (currList[currAlias] 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru && ucnv_compareNames(alias, GET_STRING(currList[currAlias]))==0) 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Search for an standard name of an alias (what is the default name 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that this standard uses?) 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return the listOffset for gTaggedAliasLists. If it's 0, 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the it couldn't be found, but the parameters are valid. 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint32_t 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerufindTaggedAliasListsOffset(const char *alias, const char *standard, UErrorCode *pErrorCode) { 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t idx; 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset; 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convNum; 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode myErr = U_ZERO_ERROR; 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t tagNum = getTagNumber(standard); 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Make a quick guess. Hopefully they used a TR22 canonical alias. */ 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru convNum = findConverter(alias, NULL, &myErr); 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myErr != U_ZERO_ERROR) { 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = myErr; 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tagNum < (gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) && convNum < gMainTable.converterListSize) { 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru listOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + convNum]; 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset && gMainTable.taggedAliasLists[listOffset + 1]) { 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return listOffset; 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myErr == U_AMBIGUOUS_ALIAS_WARNING) { 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Uh Oh! They used an ambiguous alias. 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru We have to search the whole swiss cheese starting 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru at the highest standard affinity. 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This may take a while. 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (idx = 0; idx < gMainTable.taggedAliasArraySize; idx++) { 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru listOffset = gMainTable.taggedAliasArray[idx]; 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset && isAliasInList(alias, listOffset)) { 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t currTagNum = idx/gMainTable.converterListSize; 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t currConvNum = (idx - currTagNum*gMainTable.converterListSize); 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t tempListOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + currConvNum]; 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tempListOffset && gMainTable.taggedAliasLists[tempListOffset + 1]) { 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tempListOffset; 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else keep on looking */ 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* We could speed this up by starting on the next row 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru because an alias is unique per row, right now. 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This would change if alias versioning appears. */ 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The standard doesn't know about the alias */ 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else no default name */ 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else converter or tag not found */ 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UINT32_MAX; 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Return the canonical name */ 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint32_t 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerufindTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErrorCode) { 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t idx; 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset; 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convNum; 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode myErr = U_ZERO_ERROR; 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t tagNum = getTagNumber(standard); 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Make a quick guess. Hopefully they used a TR22 canonical alias. */ 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru convNum = findConverter(alias, NULL, &myErr); 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myErr != U_ZERO_ERROR) { 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = myErr; 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tagNum < (gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) && convNum < gMainTable.converterListSize) { 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru listOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + convNum]; 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset && isAliasInList(alias, listOffset)) { 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return convNum; 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myErr == U_AMBIGUOUS_ALIAS_WARNING) { 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Uh Oh! They used an ambiguous alias. 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru We have to search one slice of the swiss cheese. 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru We search only in the requested tag, not the whole thing. 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This may take a while. 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convStart = (tagNum)*gMainTable.converterListSize; 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convLimit = (tagNum+1)*gMainTable.converterListSize; 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (idx = convStart; idx < convLimit; idx++) { 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru listOffset = gMainTable.taggedAliasArray[idx]; 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset && isAliasInList(alias, listOffset)) { 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return idx-convStart; 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* The standard doesn't know about the alias */ 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else no canonical name */ 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else converter or tag not found */ 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UINT32_MAX; 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC const char * 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) { 738103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const char *aliasTmp = alias; 739103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t i = 0; 740103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (i = 0; i < 2; i++) { 741103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (i == 1) { 742103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius /* 743103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * After the first unsuccess converter lookup, check to see if 744103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * the name begins with 'x-'. If it does, strip it off and try 745103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * again. This behaviour is similar to how ICU4J does it. 746103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius */ 747103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (aliasTmp[0] == 'x' || aliasTmp[1] == '-') { 748103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius aliasTmp = aliasTmp+2; 749103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 750103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 751103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 752103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 753103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(haveAliasData(pErrorCode) && isAlias(aliasTmp, pErrorCode)) { 754103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uint32_t convNum = findConverter(aliasTmp, containsOption, pErrorCode); 755103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (convNum < gMainTable.converterListSize) { 756103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return GET_STRING(gMainTable.converterList[convNum]); 757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 758103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius /* else converter not found */ 759103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 763103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusucnv_io_countStandardAliases(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t value = 0; 770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UAliasContext *myContext = (UAliasContext *)(enumerator->context); 771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset = myContext->listOffset; 772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset) { 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value = gMainTable.taggedAliasLists[listOffset]; 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return value; 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char* U_CALLCONV 780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_nextStandardAliases(UEnumeration *enumerator, 781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* resultLength, 782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode * /*pErrorCode*/) 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UAliasContext *myContext = (UAliasContext *)(enumerator->context); 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset = myContext->listOffset; 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset) { 788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myContext->listIdx < listCount) { 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *myStr = GET_STRING(currList[myContext->listIdx++]); 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (resultLength) { 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *resultLength = (int32_t)uprv_strlen(myStr); 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myStr; 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Either we accessed a zero length list, or we enumerated too far. */ 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (resultLength) { 801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *resultLength = 0; 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusucnv_io_resetStandardAliases(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((UAliasContext *)(enumerator->context))->listIdx = 0; 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_closeUEnumeration(UEnumeration *enumerator) { 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(enumerator->context); 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(enumerator); 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Enumerate the aliases for the specified converter and standard tag */ 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UEnumeration gEnumAliases = { 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_closeUEnumeration, 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_countStandardAliases, 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uenum_unextDefault, 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_nextStandardAliases, 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_resetStandardAliases 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UEnumeration * U_EXPORT2 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_openStandardNames(const char *convName, 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *standard, 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UEnumeration *myEnum = NULL; 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode) && isAlias(convName, pErrorCode)) { 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset = findTaggedAliasListsOffset(convName, standard, pErrorCode); 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* When listOffset == 0, we want to acknowledge that the 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter name and standard are okay, but there 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru is nothing to enumerate. */ 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset < gMainTable.taggedAliasListsSize) { 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UAliasContext *myContext; 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius myEnum = static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))); 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myEnum == NULL) { 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(myEnum, &gEnumAliases, sizeof(UEnumeration)); 84954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius myContext = static_cast<UAliasContext *>(uprv_malloc(sizeof(UAliasContext))); 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myContext == NULL) { 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(myEnum); 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myContext->listOffset = listOffset; 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myContext->listIdx = 0; 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myEnum->context = myContext; 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else converter or tag not found */ 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myEnum; 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_countAliases(const char *alias, UErrorCode *pErrorCode) { 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convNum = findConverter(alias, NULL, pErrorCode); 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (convNum < gMainTable.converterListSize) { 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* tagListNum - 1 is the ALL tag */ 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum]; 871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset) { 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gMainTable.taggedAliasLists[listOffset]; 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else this shouldn't happen. internal program error */ 876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else converter not found */ 878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_getAliases(const char *alias, uint16_t start, const char **aliases, UErrorCode *pErrorCode) { 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t currAlias; 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convNum = findConverter(alias, NULL, pErrorCode); 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (convNum < gMainTable.converterListSize) { 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* tagListNum - 1 is the ALL tag */ 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum]; 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset) { 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* +1 to skip listCount */ 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (currAlias = start; currAlias < listCount; currAlias++) { 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru aliases[currAlias] = GET_STRING(currList[currAlias]); 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else this shouldn't happen. internal program error */ 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else converter not found */ 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char * 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) { 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convNum = findConverter(alias, NULL, pErrorCode); 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (convNum < gMainTable.converterListSize) { 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* tagListNum - 1 is the ALL tag */ 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum]; 914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (listOffset) { 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* +1 to skip listCount */ 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n < listCount) { 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return GET_STRING(currList[n]); 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else this shouldn't happen. internal program error */ 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else converter not found */ 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_countStandards(UErrorCode *pErrorCode) { 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode)) { 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Don't include the empty list */ 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (uint16_t)(gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS); 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getStandard(uint16_t n, UErrorCode *pErrorCode) { 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode)) { 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n < gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) { 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return GET_STRING(gMainTable.tagList[n]); 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getStandardName(const char *alias, const char *standard, UErrorCode *pErrorCode) { 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t listOffset = findTaggedAliasListsOffset(alias, standard, pErrorCode); 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (0 < listOffset && listOffset < gMainTable.taggedAliasListsSize) { 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Get the preferred name from this list */ 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (currList[0]) { 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return GET_STRING(currList[0]); 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else someone screwed up the alias table. */ 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* *pErrorCode = U_INVALID_FORMAT_ERROR */ 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI uint16_t U_EXPORT2 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_countAliases(const char *alias, UErrorCode *pErrorCode) 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_io_countAliases(alias, pErrorCode); 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_io_getAlias(alias, n, pErrorCode); 985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode) 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_getAliases(alias, 0, aliases, pErrorCode); 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI uint16_t U_EXPORT2 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_countStandards(void) 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode err = U_ZERO_ERROR; 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ucnv_io_countStandards(&err); 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErrorCode) { 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t convNum = findTaggedConverterNum(alias, standard, pErrorCode); 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (convNum < gMainTable.converterListSize) { 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return GET_STRING(gMainTable.converterList[convNum]); 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 1014103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusucnv_io_countAllConverters(UEnumeration * /*enumerator*/, UErrorCode * /*pErrorCode*/) { 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return gMainTable.converterListSize; 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char* U_CALLCONV 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_nextAllConverters(UEnumeration *enumerator, 1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t* resultLength, 1021103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode * /*pErrorCode*/) 1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *myContext = (uint16_t *)(enumerator->context); 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*myContext < gMainTable.converterListSize) { 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *myStr = GET_STRING(gMainTable.converterList[(*myContext)++]); 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (resultLength) { 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *resultLength = (int32_t)uprv_strlen(myStr); 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myStr; 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Either we accessed a zero length list, or we enumerated too far. */ 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (resultLength) { 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *resultLength = 0; 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 1040103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusucnv_io_resetAllConverters(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *((uint16_t *)(enumerator->context)) = 0; 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UEnumeration gEnumAllConverters = { 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_closeUEnumeration, 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_countAllConverters, 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uenum_unextDefault, 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_nextAllConverters, 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_io_resetAllConverters 1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UEnumeration * U_EXPORT2 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_openAllNames(UErrorCode *pErrorCode) { 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UEnumeration *myEnum = NULL; 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode)) { 1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *myContext; 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 106054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius myEnum = static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))); 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myEnum == NULL) { 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(myEnum, &gEnumAllConverters, sizeof(UEnumeration)); 106654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius myContext = static_cast<uint16_t *>(uprv_malloc(sizeof(uint16_t))); 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (myContext == NULL) { 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(myEnum); 1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *myContext = 0; 1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru myEnum->context = myContext; 1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return myEnum; 1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC uint16_t 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_io_countKnownConverters(UErrorCode *pErrorCode) { 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveAliasData(pErrorCode)) { 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (uint16_t)gMainTable.converterListSize; 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* alias table swapping ----------------------------------------------------- */ 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef char * U_CALLCONV StripForCompareFn(char *dst, const char *name); 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * row of a temporary array 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * gets platform-endian charset string indexes and sorting indexes; 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * after sorting this array by strings, the actual arrays are permutated 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * according to the sorting indexes 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct TempRow { 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t strIndex, sortIndex; 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} TempRow; 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct TempAliasTable { 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *chars; 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TempRow *rows; 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *resort; 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StripForCompareFn *stripForCompare; 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} TempAliasTable; 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru STACK_ROW_CAPACITY=500 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruio_compareRows(const void *context, const void *left, const void *right) { 1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char strippedLeft[UCNV_MAX_CONVERTER_NAME_LENGTH], 1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru strippedRight[UCNV_MAX_CONVERTER_NAME_LENGTH]; 1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TempAliasTable *tempTable=(TempAliasTable *)context; 1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *chars=tempTable->chars; 1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (int32_t)uprv_strcmp(tempTable->stripForCompare(strippedLeft, chars+2*((const TempRow *)left)->strIndex), 1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable->stripForCompare(strippedRight, chars+2*((const TempRow *)right)->strIndex)); 1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_swapAliases(const UDataSwapper *ds, 1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataInfo *pInfo; 1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t headerSize; 1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *inTable; 1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint32_t *inSectionSizes; 1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t toc[offsetsCount]; 1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t offsets[offsetsCount]; /* 16-bit-addressed offsets from inTable/outTable */ 1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t i, count, tocLength, topOffset; 1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TempRow rows[STACK_ROW_CAPACITY]; 1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t resort[STACK_ROW_CAPACITY]; 1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TempAliasTable tempTable; 1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check data format and format version */ 1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!( 1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x43 && /* dataFormat="CvAl" */ 1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x76 && 1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x41 && 1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x6c && 1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==3 1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru )) { 1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases(): data format %02x.%02x.%02x.%02x (format version %02x) is not an alias table\n", 1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]); 1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* an alias table must contain at least the table of contents array */ 1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0 && (length-headerSize)<4*(1+minTocLength)) { 1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases(): too few bytes (%d after header) for an alias table\n", 1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-headerSize); 1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inSectionSizes=(const uint32_t *)((const char *)inData+headerSize); 1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inTable=(const uint16_t *)inSectionSizes; 1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(toc, 0, sizeof(toc)); 1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toc[tocLengthIndex]=tocLength=ds->readUInt32(inSectionSizes[tocLengthIndex]); 1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(tocLength<minTocLength || offsetsCount<=tocLength) { 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases(): table of contents contains unsupported number of sections (%u sections)\n", tocLength); 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INVALID_FORMAT_ERROR; 1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the known part of the table of contents */ 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=converterListIndex; i<=tocLength; ++i) { 1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toc[i]=ds->readUInt32(inSectionSizes[i]); 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* compute offsets */ 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(offsets, 0, sizeof(offsets)); 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets[converterListIndex]=2*(1+tocLength); /* count two 16-bit units per toc entry */ 1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=tagListIndex; i<=tocLength; ++i) { 1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsets[i]=offsets[i-1]+toc[i-1]; 1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* compute the overall size of the after-header data, in numbers of 16-bit units */ 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru topOffset=offsets[i-1]+toc[i-1]; 1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>=0) { 1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *outTable; 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *p, *p2; 1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *q, *q2; 1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t oldIndex; 1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((length-headerSize)<(2*(int32_t)topOffset)) { 1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases(): too few bytes (%d after header) for an alias table\n", 1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-headerSize); 1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outTable=(uint16_t *)((char *)outData+headerSize); 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the entire table of contents */ 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inTable, 4*(1+tocLength), outTable, pErrorCode); 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap unormalized strings & normalized strings */ 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapInvChars(ds, inTable+offsets[stringTableIndex], 2*(int32_t)(toc[stringTableIndex]+toc[normalizedStringTableIndex]), 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outTable+offsets[stringTableIndex], pErrorCode); 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases().swapInvChars(charset names) failed\n"); 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds->inCharset==ds->outCharset) { 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no need to sort, just swap all 16-bit values together */ 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inTable+offsets[converterListIndex], 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2*(int32_t)(offsets[stringTableIndex]-offsets[converterListIndex]), 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outTable+offsets[converterListIndex], 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allocate the temporary table for sorting */ 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=toc[aliasListIndex]; 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.chars=(const char *)(outTable+offsets[stringTableIndex]); /* sort by outCharset */ 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(count<=STACK_ROW_CAPACITY) { 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.rows=rows; 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.resort=resort; 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.rows=(TempRow *)uprv_malloc(count*sizeof(TempRow)+count*2); 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(tempTable.rows==NULL) { 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases(): unable to allocate memory for sorting tables (max length: %u)\n", 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count); 1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.resort=(uint16_t *)(tempTable.rows+count); 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds->outCharset==U_ASCII_FAMILY) { 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.stripForCompare=ucnv_io_stripASCIIForCompare; 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else /* U_EBCDIC_FAMILY */ { 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.stripForCompare=ucnv_io_stripEBCDICForCompare; 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Sort unique aliases+mapped names. 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We need to sort the list again by outCharset strings because they 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * sort differently for different charset families. 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * First we set up a temporary table with the string indexes and 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * sorting indexes and sort that. 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Then we permutate and copy/swap the actual values. 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p=inTable+offsets[aliasListIndex]; 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru q=outTable+offsets[aliasListIndex]; 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p2=inTable+offsets[untaggedConvArrayIndex]; 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru q2=outTable+offsets[untaggedConvArrayIndex]; 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<count; ++i) { 1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.rows[i].strIndex=ds->readUInt16(p[i]); 1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tempTable.rows[i].sortIndex=(uint16_t)i; 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_sortArray(tempTable.rows, (int32_t)count, sizeof(TempRow), 1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru io_compareRows, &tempTable, 1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FALSE, pErrorCode); 1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*pErrorCode)) { 1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy/swap/permutate items */ 1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(p!=q) { 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<count; ++i) { 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru oldIndex=tempTable.rows[i].sortIndex; 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, p+oldIndex, 2, q+i, pErrorCode); 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, p2+oldIndex, 2, q2+i, pErrorCode); 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If we swap in-place, then the permutation must use another 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * temporary array (tempTable.resort) 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * before the results are copied to the outBundle. 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *r=tempTable.resort; 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<count; ++i) { 1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru oldIndex=tempTable.rows[i].sortIndex; 1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, p+oldIndex, 2, r+i, pErrorCode); 1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(q, r, 2*count); 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<count; ++i) { 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru oldIndex=tempTable.rows[i].sortIndex; 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, p2+oldIndex, 2, r+i, pErrorCode); 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(q2, r, 2*count); 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(tempTable.rows!=rows) { 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(tempTable.rows); 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "ucnv_swapAliases().uprv_sortArray(%u items) failed\n", 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count); 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap remaining 16-bit values */ 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, 1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inTable+offsets[converterListIndex], 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2*(int32_t)(offsets[aliasListIndex]-offsets[converterListIndex]), 1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outTable+offsets[converterListIndex], 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inTable+offsets[taggedAliasArrayIndex], 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2*(int32_t)(offsets[stringTableIndex]-offsets[taggedAliasArrayIndex]), 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outTable+offsets[taggedAliasArrayIndex], 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+2*(int32_t)topOffset; 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 133959d709d503bab6e2b61931737e662dd293b40578ccornelius 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Hey, Emacs, please set the following: 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Local Variables: 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * indent-tabs-mode: nil 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * End: 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1348