11cb0ef41Sopenharmony_ci// © 2016 and later: Unicode, Inc. and others. 21cb0ef41Sopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html 31cb0ef41Sopenharmony_ci/* 41cb0ef41Sopenharmony_ci****************************************************************************** 51cb0ef41Sopenharmony_ci* 61cb0ef41Sopenharmony_ci* Copyright (C) 1999-2015, International Business Machines 71cb0ef41Sopenharmony_ci* Corporation and others. All Rights Reserved. 81cb0ef41Sopenharmony_ci* 91cb0ef41Sopenharmony_ci****************************************************************************** 101cb0ef41Sopenharmony_ci* 111cb0ef41Sopenharmony_ci* 121cb0ef41Sopenharmony_ci* ucnv_io.cpp: 131cb0ef41Sopenharmony_ci* initializes global variables and defines functions pertaining to converter 141cb0ef41Sopenharmony_ci* name resolution aspect of the conversion code. 151cb0ef41Sopenharmony_ci* 161cb0ef41Sopenharmony_ci* new implementation: 171cb0ef41Sopenharmony_ci* 181cb0ef41Sopenharmony_ci* created on: 1999nov22 191cb0ef41Sopenharmony_ci* created by: Markus W. Scherer 201cb0ef41Sopenharmony_ci* 211cb0ef41Sopenharmony_ci* Use the binary cnvalias.icu (created from convrtrs.txt) to work 221cb0ef41Sopenharmony_ci* with aliases for converter names. 231cb0ef41Sopenharmony_ci* 241cb0ef41Sopenharmony_ci* Date Name Description 251cb0ef41Sopenharmony_ci* 11/22/1999 markus Created 261cb0ef41Sopenharmony_ci* 06/28/2002 grhoten Major overhaul of the converter alias design. 271cb0ef41Sopenharmony_ci* Now an alias can map to different converters 281cb0ef41Sopenharmony_ci* depending on the specified standard. 291cb0ef41Sopenharmony_ci******************************************************************************* 301cb0ef41Sopenharmony_ci*/ 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include "unicode/utypes.h" 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci#if !UCONFIG_NO_CONVERSION 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci#include "unicode/ucnv.h" 371cb0ef41Sopenharmony_ci#include "unicode/udata.h" 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci#include "umutex.h" 401cb0ef41Sopenharmony_ci#include "uarrsort.h" 411cb0ef41Sopenharmony_ci#include "uassert.h" 421cb0ef41Sopenharmony_ci#include "udataswp.h" 431cb0ef41Sopenharmony_ci#include "cstring.h" 441cb0ef41Sopenharmony_ci#include "cmemory.h" 451cb0ef41Sopenharmony_ci#include "ucnv_io.h" 461cb0ef41Sopenharmony_ci#include "uenumimp.h" 471cb0ef41Sopenharmony_ci#include "ucln_cmn.h" 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci/* Format of cnvalias.icu ----------------------------------------------------- 501cb0ef41Sopenharmony_ci * 511cb0ef41Sopenharmony_ci * cnvalias.icu is a binary, memory-mappable form of convrtrs.txt. 521cb0ef41Sopenharmony_ci * This binary form contains several tables. All indexes are to uint16_t 531cb0ef41Sopenharmony_ci * units, and not to the bytes (uint8_t units). Addressing everything on 541cb0ef41Sopenharmony_ci * 16-bit boundaries allows us to store more information with small index 551cb0ef41Sopenharmony_ci * numbers, which are also 16-bit in size. The majority of the table (except 561cb0ef41Sopenharmony_ci * the string table) are 16-bit numbers. 571cb0ef41Sopenharmony_ci * 581cb0ef41Sopenharmony_ci * First there is the size of the Table of Contents (TOC). The TOC 591cb0ef41Sopenharmony_ci * entries contain the size of each section. In order to find the offset 601cb0ef41Sopenharmony_ci * you just need to sum up the previous offsets. 611cb0ef41Sopenharmony_ci * The TOC length and entries are an array of uint32_t values. 621cb0ef41Sopenharmony_ci * The first section after the TOC starts immediately after the TOC. 631cb0ef41Sopenharmony_ci * 641cb0ef41Sopenharmony_ci * 1) This section contains a list of converters. This list contains indexes 651cb0ef41Sopenharmony_ci * into the string table for the converter name. The index of this list is 661cb0ef41Sopenharmony_ci * also used by other sections, which are mentioned later on. 671cb0ef41Sopenharmony_ci * This list is not sorted. 681cb0ef41Sopenharmony_ci * 691cb0ef41Sopenharmony_ci * 2) This section contains a list of tags. This list contains indexes 701cb0ef41Sopenharmony_ci * into the string table for the tag name. The index of this list is 711cb0ef41Sopenharmony_ci * also used by other sections, which are mentioned later on. 721cb0ef41Sopenharmony_ci * This list is in priority order of standards. 731cb0ef41Sopenharmony_ci * 741cb0ef41Sopenharmony_ci * 3) This section contains a list of sorted unique aliases. This 751cb0ef41Sopenharmony_ci * list contains indexes into the string table for the alias name. The 761cb0ef41Sopenharmony_ci * index of this list is also used by other sections, like the 4th section. 771cb0ef41Sopenharmony_ci * The index for the 3rd and 4th section is used to get the 781cb0ef41Sopenharmony_ci * alias -> converter name mapping. Section 3 and 4 form a two column table. 791cb0ef41Sopenharmony_ci * Some of the most significant bits of each index may contain other 801cb0ef41Sopenharmony_ci * information (see findConverter for details). 811cb0ef41Sopenharmony_ci * 821cb0ef41Sopenharmony_ci * 4) This section contains a list of mapped converter names. Consider this 831cb0ef41Sopenharmony_ci * as a table that maps the 3rd section to the 1st section. This list contains 841cb0ef41Sopenharmony_ci * indexes into the 1st section. The index of this list is the same index in 851cb0ef41Sopenharmony_ci * the 3rd section. There is also some extra information in the high bits of 861cb0ef41Sopenharmony_ci * each converter index in this table. Currently it's only used to say that 871cb0ef41Sopenharmony_ci * an alias mapped to this converter is ambiguous. See UCNV_CONVERTER_INDEX_MASK 881cb0ef41Sopenharmony_ci * and UCNV_AMBIGUOUS_ALIAS_MAP_BIT for more information. This section is 891cb0ef41Sopenharmony_ci * the predigested form of the 5th section so that an alias lookup can be fast. 901cb0ef41Sopenharmony_ci * 911cb0ef41Sopenharmony_ci * 5) This section contains a 2D array with indexes to the 6th section. This 921cb0ef41Sopenharmony_ci * section is the full form of all alias mappings. The column index is the 931cb0ef41Sopenharmony_ci * index into the converter list (column header). The row index is the index 941cb0ef41Sopenharmony_ci * to tag list (row header). This 2D array is the top part a 3D array. The 951cb0ef41Sopenharmony_ci * third dimension is in the 6th section. 961cb0ef41Sopenharmony_ci * 971cb0ef41Sopenharmony_ci * 6) This is blob of variable length arrays. Each array starts with a size, 981cb0ef41Sopenharmony_ci * and is followed by indexes to alias names in the string table. This is 991cb0ef41Sopenharmony_ci * the third dimension to the section 5. No other section should be referencing 1001cb0ef41Sopenharmony_ci * this section. 1011cb0ef41Sopenharmony_ci * 1021cb0ef41Sopenharmony_ci * 7) Starting in ICU 3.6, this can be a UConverterAliasOptions struct. Its 1031cb0ef41Sopenharmony_ci * presence indicates that a section 9 exists. UConverterAliasOptions specifies 1041cb0ef41Sopenharmony_ci * what type of string normalization is used among other potential things in the 1051cb0ef41Sopenharmony_ci * future. 1061cb0ef41Sopenharmony_ci * 1071cb0ef41Sopenharmony_ci * 8) This is the string table. All strings are indexed on an even address. 1081cb0ef41Sopenharmony_ci * There are two reasons for this. First many chip architectures locate strings 1091cb0ef41Sopenharmony_ci * faster on even address boundaries. Second, since all indexes are 16-bit 1101cb0ef41Sopenharmony_ci * numbers, this string table can be 128KB in size instead of 64KB when we 1111cb0ef41Sopenharmony_ci * only have strings starting on an even address. 1121cb0ef41Sopenharmony_ci * 1131cb0ef41Sopenharmony_ci * 9) When present this is a set of prenormalized strings from section 8. This 1141cb0ef41Sopenharmony_ci * table contains normalized strings with the dashes and spaces stripped out, 1151cb0ef41Sopenharmony_ci * and all strings lowercased. In the future, the options in section 7 may state 1161cb0ef41Sopenharmony_ci * other types of normalization. 1171cb0ef41Sopenharmony_ci * 1181cb0ef41Sopenharmony_ci * Here is the concept of section 5 and 6. It's a 3D cube. Each tag 1191cb0ef41Sopenharmony_ci * has a unique alias among all converters. That same alias can 1201cb0ef41Sopenharmony_ci * be mentioned in other standards on different converters, 1211cb0ef41Sopenharmony_ci * but only one alias per tag can be unique. 1221cb0ef41Sopenharmony_ci * 1231cb0ef41Sopenharmony_ci * 1241cb0ef41Sopenharmony_ci * Converter Names (Usually in TR22 form) 1251cb0ef41Sopenharmony_ci * -------------------------------------------. 1261cb0ef41Sopenharmony_ci * T / /| 1271cb0ef41Sopenharmony_ci * a / / | 1281cb0ef41Sopenharmony_ci * g / / | 1291cb0ef41Sopenharmony_ci * s / / | 1301cb0ef41Sopenharmony_ci * / / | 1311cb0ef41Sopenharmony_ci * ------------------------------------------/ | 1321cb0ef41Sopenharmony_ci * A | | | 1331cb0ef41Sopenharmony_ci * l | | | 1341cb0ef41Sopenharmony_ci * i | | / 1351cb0ef41Sopenharmony_ci * a | | / 1361cb0ef41Sopenharmony_ci * s | | / 1371cb0ef41Sopenharmony_ci * e | | / 1381cb0ef41Sopenharmony_ci * s | |/ 1391cb0ef41Sopenharmony_ci * ------------------------------------------- 1401cb0ef41Sopenharmony_ci * 1411cb0ef41Sopenharmony_ci * 1421cb0ef41Sopenharmony_ci * 1431cb0ef41Sopenharmony_ci * Here is what it really looks like. It's like swiss cheese. 1441cb0ef41Sopenharmony_ci * There are holes. Some converters aren't recognized by 1451cb0ef41Sopenharmony_ci * a standard, or they are really old converters that the 1461cb0ef41Sopenharmony_ci * standard doesn't recognize anymore. 1471cb0ef41Sopenharmony_ci * 1481cb0ef41Sopenharmony_ci * Converter Names (Usually in TR22 form) 1491cb0ef41Sopenharmony_ci * -------------------------------------------. 1501cb0ef41Sopenharmony_ci * T /##########################################/| 1511cb0ef41Sopenharmony_ci * a / # # /# 1521cb0ef41Sopenharmony_ci * g / # ## ## ### # ### ### ### #/ 1531cb0ef41Sopenharmony_ci * s / # ##### #### ## ## #/# 1541cb0ef41Sopenharmony_ci * / ### # # ## # # # ### # # #/## 1551cb0ef41Sopenharmony_ci * ------------------------------------------/# # 1561cb0ef41Sopenharmony_ci * A |### # # ## # # # ### # # #|# # 1571cb0ef41Sopenharmony_ci * l |# # # # # ## # #|# # 1581cb0ef41Sopenharmony_ci * i |# # # # # # #|# 1591cb0ef41Sopenharmony_ci * a |# #|# 1601cb0ef41Sopenharmony_ci * s | #|# 1611cb0ef41Sopenharmony_ci * e 1621cb0ef41Sopenharmony_ci * s 1631cb0ef41Sopenharmony_ci * 1641cb0ef41Sopenharmony_ci */ 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci/** 1671cb0ef41Sopenharmony_ci * Used by the UEnumeration API 1681cb0ef41Sopenharmony_ci */ 1691cb0ef41Sopenharmony_citypedef struct UAliasContext { 1701cb0ef41Sopenharmony_ci uint32_t listOffset; 1711cb0ef41Sopenharmony_ci uint32_t listIdx; 1721cb0ef41Sopenharmony_ci} UAliasContext; 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_cistatic const char DATA_NAME[] = "cnvalias"; 1751cb0ef41Sopenharmony_cistatic const char DATA_TYPE[] = "icu"; 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_cistatic UDataMemory *gAliasData=nullptr; 1781cb0ef41Sopenharmony_cistatic icu::UInitOnce gAliasDataInitOnce {}; 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_cienum { 1811cb0ef41Sopenharmony_ci tocLengthIndex=0, 1821cb0ef41Sopenharmony_ci converterListIndex=1, 1831cb0ef41Sopenharmony_ci tagListIndex=2, 1841cb0ef41Sopenharmony_ci aliasListIndex=3, 1851cb0ef41Sopenharmony_ci untaggedConvArrayIndex=4, 1861cb0ef41Sopenharmony_ci taggedAliasArrayIndex=5, 1871cb0ef41Sopenharmony_ci taggedAliasListsIndex=6, 1881cb0ef41Sopenharmony_ci tableOptionsIndex=7, 1891cb0ef41Sopenharmony_ci stringTableIndex=8, 1901cb0ef41Sopenharmony_ci normalizedStringTableIndex=9, 1911cb0ef41Sopenharmony_ci offsetsCount, /* length of the swapper's temporary offsets[] */ 1921cb0ef41Sopenharmony_ci minTocLength=8 /* min. tocLength in the file, does not count the tocLengthIndex! */ 1931cb0ef41Sopenharmony_ci}; 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_cistatic const UConverterAliasOptions defaultTableOptions = { 1961cb0ef41Sopenharmony_ci UCNV_IO_UNNORMALIZED, 1971cb0ef41Sopenharmony_ci 0 /* containsCnvOptionInfo */ 1981cb0ef41Sopenharmony_ci}; 1991cb0ef41Sopenharmony_cistatic UConverterAlias gMainTable; 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci#define GET_STRING(idx) (const char *)(gMainTable.stringTable + (idx)) 2021cb0ef41Sopenharmony_ci#define GET_NORMALIZED_STRING(idx) (const char *)(gMainTable.normalizedStringTable + (idx)) 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_cistatic UBool U_CALLCONV 2051cb0ef41Sopenharmony_ciisAcceptable(void * /*context*/, 2061cb0ef41Sopenharmony_ci const char * /*type*/, const char * /*name*/, 2071cb0ef41Sopenharmony_ci const UDataInfo *pInfo) { 2081cb0ef41Sopenharmony_ci return (UBool)( 2091cb0ef41Sopenharmony_ci pInfo->size>=20 && 2101cb0ef41Sopenharmony_ci pInfo->isBigEndian==U_IS_BIG_ENDIAN && 2111cb0ef41Sopenharmony_ci pInfo->charsetFamily==U_CHARSET_FAMILY && 2121cb0ef41Sopenharmony_ci pInfo->dataFormat[0]==0x43 && /* dataFormat="CvAl" */ 2131cb0ef41Sopenharmony_ci pInfo->dataFormat[1]==0x76 && 2141cb0ef41Sopenharmony_ci pInfo->dataFormat[2]==0x41 && 2151cb0ef41Sopenharmony_ci pInfo->dataFormat[3]==0x6c && 2161cb0ef41Sopenharmony_ci pInfo->formatVersion[0]==3); 2171cb0ef41Sopenharmony_ci} 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_cistatic UBool U_CALLCONV ucnv_io_cleanup() 2201cb0ef41Sopenharmony_ci{ 2211cb0ef41Sopenharmony_ci if (gAliasData) { 2221cb0ef41Sopenharmony_ci udata_close(gAliasData); 2231cb0ef41Sopenharmony_ci gAliasData = nullptr; 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ci gAliasDataInitOnce.reset(); 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci uprv_memset(&gMainTable, 0, sizeof(gMainTable)); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci return true; /* Everything was cleaned up */ 2301cb0ef41Sopenharmony_ci} 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_cistatic void U_CALLCONV initAliasData(UErrorCode &errCode) { 2331cb0ef41Sopenharmony_ci UDataMemory *data; 2341cb0ef41Sopenharmony_ci const uint16_t *table; 2351cb0ef41Sopenharmony_ci const uint32_t *sectionSizes; 2361cb0ef41Sopenharmony_ci uint32_t tableStart; 2371cb0ef41Sopenharmony_ci uint32_t currOffset; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup); 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci U_ASSERT(gAliasData == nullptr); 2421cb0ef41Sopenharmony_ci data = udata_openChoice(nullptr, DATA_TYPE, DATA_NAME, isAcceptable, nullptr, &errCode); 2431cb0ef41Sopenharmony_ci if(U_FAILURE(errCode)) { 2441cb0ef41Sopenharmony_ci return; 2451cb0ef41Sopenharmony_ci } 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci sectionSizes = (const uint32_t *)udata_getMemory(data); 2481cb0ef41Sopenharmony_ci table = (const uint16_t *)sectionSizes; 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci tableStart = sectionSizes[0]; 2511cb0ef41Sopenharmony_ci if (tableStart < minTocLength) { 2521cb0ef41Sopenharmony_ci errCode = U_INVALID_FORMAT_ERROR; 2531cb0ef41Sopenharmony_ci udata_close(data); 2541cb0ef41Sopenharmony_ci return; 2551cb0ef41Sopenharmony_ci } 2561cb0ef41Sopenharmony_ci gAliasData = data; 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci gMainTable.converterListSize = sectionSizes[1]; 2591cb0ef41Sopenharmony_ci gMainTable.tagListSize = sectionSizes[2]; 2601cb0ef41Sopenharmony_ci gMainTable.aliasListSize = sectionSizes[3]; 2611cb0ef41Sopenharmony_ci gMainTable.untaggedConvArraySize = sectionSizes[4]; 2621cb0ef41Sopenharmony_ci gMainTable.taggedAliasArraySize = sectionSizes[5]; 2631cb0ef41Sopenharmony_ci gMainTable.taggedAliasListsSize = sectionSizes[6]; 2641cb0ef41Sopenharmony_ci gMainTable.optionTableSize = sectionSizes[7]; 2651cb0ef41Sopenharmony_ci gMainTable.stringTableSize = sectionSizes[8]; 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci if (tableStart > 8) { 2681cb0ef41Sopenharmony_ci gMainTable.normalizedStringTableSize = sectionSizes[9]; 2691cb0ef41Sopenharmony_ci } 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t)); 2721cb0ef41Sopenharmony_ci gMainTable.converterList = table + currOffset; 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci currOffset += gMainTable.converterListSize; 2751cb0ef41Sopenharmony_ci gMainTable.tagList = table + currOffset; 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci currOffset += gMainTable.tagListSize; 2781cb0ef41Sopenharmony_ci gMainTable.aliasList = table + currOffset; 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci currOffset += gMainTable.aliasListSize; 2811cb0ef41Sopenharmony_ci gMainTable.untaggedConvArray = table + currOffset; 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci currOffset += gMainTable.untaggedConvArraySize; 2841cb0ef41Sopenharmony_ci gMainTable.taggedAliasArray = table + currOffset; 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci /* aliasLists is a 1's based array, but it has a padding character */ 2871cb0ef41Sopenharmony_ci currOffset += gMainTable.taggedAliasArraySize; 2881cb0ef41Sopenharmony_ci gMainTable.taggedAliasLists = table + currOffset; 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci currOffset += gMainTable.taggedAliasListsSize; 2911cb0ef41Sopenharmony_ci if (gMainTable.optionTableSize > 0 2921cb0ef41Sopenharmony_ci && ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT) 2931cb0ef41Sopenharmony_ci { 2941cb0ef41Sopenharmony_ci /* Faster table */ 2951cb0ef41Sopenharmony_ci gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset); 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci else { 2981cb0ef41Sopenharmony_ci /* Smaller table, or I can't handle this normalization mode! 2991cb0ef41Sopenharmony_ci Use the original slower table lookup. */ 3001cb0ef41Sopenharmony_ci gMainTable.optionTable = &defaultTableOptions; 3011cb0ef41Sopenharmony_ci } 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci currOffset += gMainTable.optionTableSize; 3041cb0ef41Sopenharmony_ci gMainTable.stringTable = table + currOffset; 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci currOffset += gMainTable.stringTableSize; 3071cb0ef41Sopenharmony_ci gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED) 3081cb0ef41Sopenharmony_ci ? gMainTable.stringTable : (table + currOffset)); 3091cb0ef41Sopenharmony_ci} 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_cistatic UBool 3131cb0ef41Sopenharmony_cihaveAliasData(UErrorCode *pErrorCode) { 3141cb0ef41Sopenharmony_ci umtx_initOnce(gAliasDataInitOnce, &initAliasData, *pErrorCode); 3151cb0ef41Sopenharmony_ci return U_SUCCESS(*pErrorCode); 3161cb0ef41Sopenharmony_ci} 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_cistatic inline UBool 3191cb0ef41Sopenharmony_ciisAlias(const char *alias, UErrorCode *pErrorCode) { 3201cb0ef41Sopenharmony_ci if(alias==nullptr) { 3211cb0ef41Sopenharmony_ci *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 3221cb0ef41Sopenharmony_ci return false; 3231cb0ef41Sopenharmony_ci } 3241cb0ef41Sopenharmony_ci return (UBool)(*alias!=0); 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_cistatic uint32_t getTagNumber(const char *tagname) { 3281cb0ef41Sopenharmony_ci if (gMainTable.tagList) { 3291cb0ef41Sopenharmony_ci uint32_t tagNum; 3301cb0ef41Sopenharmony_ci for (tagNum = 0; tagNum < gMainTable.tagListSize; tagNum++) { 3311cb0ef41Sopenharmony_ci if (!uprv_stricmp(GET_STRING(gMainTable.tagList[tagNum]), tagname)) { 3321cb0ef41Sopenharmony_ci return tagNum; 3331cb0ef41Sopenharmony_ci } 3341cb0ef41Sopenharmony_ci } 3351cb0ef41Sopenharmony_ci } 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ci return UINT32_MAX; 3381cb0ef41Sopenharmony_ci} 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci/* character types relevant for ucnv_compareNames() */ 3411cb0ef41Sopenharmony_cienum { 3421cb0ef41Sopenharmony_ci UIGNORE, 3431cb0ef41Sopenharmony_ci ZERO, 3441cb0ef41Sopenharmony_ci NONZERO, 3451cb0ef41Sopenharmony_ci MINLETTER /* any values from here on are lowercase letter mappings */ 3461cb0ef41Sopenharmony_ci}; 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci/* character types for ASCII 00..7F */ 3491cb0ef41Sopenharmony_cistatic const uint8_t asciiTypes[128] = { 3501cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3521cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3531cb0ef41Sopenharmony_ci ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0, 3541cb0ef41Sopenharmony_ci 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 3551cb0ef41Sopenharmony_ci 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0, 3561cb0ef41Sopenharmony_ci 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 3571cb0ef41Sopenharmony_ci 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0 3581cb0ef41Sopenharmony_ci}; 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)UIGNORE) 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci/* character types for EBCDIC 80..FF */ 3631cb0ef41Sopenharmony_cistatic const uint8_t ebcdicTypes[128] = { 3641cb0ef41Sopenharmony_ci 0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0, 0, 0, 0, 0, 0, 3651cb0ef41Sopenharmony_ci 0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0, 0, 0, 0, 0, 0, 3661cb0ef41Sopenharmony_ci 0, 0, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0, 0, 0, 0, 0, 0, 3671cb0ef41Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3681cb0ef41Sopenharmony_ci 0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0, 0, 0, 0, 0, 0, 3691cb0ef41Sopenharmony_ci 0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0, 0, 0, 0, 0, 0, 3701cb0ef41Sopenharmony_ci 0, 0, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0, 0, 0, 0, 0, 0, 3711cb0ef41Sopenharmony_ci ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0 3721cb0ef41Sopenharmony_ci}; 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)UIGNORE) 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ci#if U_CHARSET_FAMILY==U_ASCII_FAMILY 3771cb0ef41Sopenharmony_ci# define GET_CHAR_TYPE(c) GET_ASCII_TYPE(c) 3781cb0ef41Sopenharmony_ci#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY 3791cb0ef41Sopenharmony_ci# define GET_CHAR_TYPE(c) GET_EBCDIC_TYPE(c) 3801cb0ef41Sopenharmony_ci#else 3811cb0ef41Sopenharmony_ci# error U_CHARSET_FAMILY is not valid 3821cb0ef41Sopenharmony_ci#endif 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci/* @see ucnv_compareNames */ 3861cb0ef41Sopenharmony_ciU_CAPI char * U_CALLCONV 3871cb0ef41Sopenharmony_ciucnv_io_stripASCIIForCompare(char *dst, const char *name) { 3881cb0ef41Sopenharmony_ci char *dstItr = dst; 3891cb0ef41Sopenharmony_ci uint8_t type, nextType; 3901cb0ef41Sopenharmony_ci char c1; 3911cb0ef41Sopenharmony_ci UBool afterDigit = false; 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci while ((c1 = *name++) != 0) { 3941cb0ef41Sopenharmony_ci type = GET_ASCII_TYPE(c1); 3951cb0ef41Sopenharmony_ci switch (type) { 3961cb0ef41Sopenharmony_ci case UIGNORE: 3971cb0ef41Sopenharmony_ci afterDigit = false; 3981cb0ef41Sopenharmony_ci continue; /* ignore all but letters and digits */ 3991cb0ef41Sopenharmony_ci case ZERO: 4001cb0ef41Sopenharmony_ci if (!afterDigit) { 4011cb0ef41Sopenharmony_ci nextType = GET_ASCII_TYPE(*name); 4021cb0ef41Sopenharmony_ci if (nextType == ZERO || nextType == NONZERO) { 4031cb0ef41Sopenharmony_ci continue; /* ignore leading zero before another digit */ 4041cb0ef41Sopenharmony_ci } 4051cb0ef41Sopenharmony_ci } 4061cb0ef41Sopenharmony_ci break; 4071cb0ef41Sopenharmony_ci case NONZERO: 4081cb0ef41Sopenharmony_ci afterDigit = true; 4091cb0ef41Sopenharmony_ci break; 4101cb0ef41Sopenharmony_ci default: 4111cb0ef41Sopenharmony_ci c1 = (char)type; /* lowercased letter */ 4121cb0ef41Sopenharmony_ci afterDigit = false; 4131cb0ef41Sopenharmony_ci break; 4141cb0ef41Sopenharmony_ci } 4151cb0ef41Sopenharmony_ci *dstItr++ = c1; 4161cb0ef41Sopenharmony_ci } 4171cb0ef41Sopenharmony_ci *dstItr = 0; 4181cb0ef41Sopenharmony_ci return dst; 4191cb0ef41Sopenharmony_ci} 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ciU_CAPI char * U_CALLCONV 4221cb0ef41Sopenharmony_ciucnv_io_stripEBCDICForCompare(char *dst, const char *name) { 4231cb0ef41Sopenharmony_ci char *dstItr = dst; 4241cb0ef41Sopenharmony_ci uint8_t type, nextType; 4251cb0ef41Sopenharmony_ci char c1; 4261cb0ef41Sopenharmony_ci UBool afterDigit = false; 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci while ((c1 = *name++) != 0) { 4291cb0ef41Sopenharmony_ci type = GET_EBCDIC_TYPE(c1); 4301cb0ef41Sopenharmony_ci switch (type) { 4311cb0ef41Sopenharmony_ci case UIGNORE: 4321cb0ef41Sopenharmony_ci afterDigit = false; 4331cb0ef41Sopenharmony_ci continue; /* ignore all but letters and digits */ 4341cb0ef41Sopenharmony_ci case ZERO: 4351cb0ef41Sopenharmony_ci if (!afterDigit) { 4361cb0ef41Sopenharmony_ci nextType = GET_EBCDIC_TYPE(*name); 4371cb0ef41Sopenharmony_ci if (nextType == ZERO || nextType == NONZERO) { 4381cb0ef41Sopenharmony_ci continue; /* ignore leading zero before another digit */ 4391cb0ef41Sopenharmony_ci } 4401cb0ef41Sopenharmony_ci } 4411cb0ef41Sopenharmony_ci break; 4421cb0ef41Sopenharmony_ci case NONZERO: 4431cb0ef41Sopenharmony_ci afterDigit = true; 4441cb0ef41Sopenharmony_ci break; 4451cb0ef41Sopenharmony_ci default: 4461cb0ef41Sopenharmony_ci c1 = (char)type; /* lowercased letter */ 4471cb0ef41Sopenharmony_ci afterDigit = false; 4481cb0ef41Sopenharmony_ci break; 4491cb0ef41Sopenharmony_ci } 4501cb0ef41Sopenharmony_ci *dstItr++ = c1; 4511cb0ef41Sopenharmony_ci } 4521cb0ef41Sopenharmony_ci *dstItr = 0; 4531cb0ef41Sopenharmony_ci return dst; 4541cb0ef41Sopenharmony_ci} 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci/** 4571cb0ef41Sopenharmony_ci * Do a fuzzy compare of two converter/alias names. 4581cb0ef41Sopenharmony_ci * The comparison is case-insensitive, ignores leading zeroes if they are not 4591cb0ef41Sopenharmony_ci * followed by further digits, and ignores all but letters and digits. 4601cb0ef41Sopenharmony_ci * Thus the strings "UTF-8", "utf_8", "u*T@f08" and "Utf 8" are exactly equivalent. 4611cb0ef41Sopenharmony_ci * See section 1.4, Charset Alias Matching in Unicode Technical Standard #22 4621cb0ef41Sopenharmony_ci * at http://www.unicode.org/reports/tr22/ 4631cb0ef41Sopenharmony_ci * 4641cb0ef41Sopenharmony_ci * This is a symmetrical (commutative) operation; order of arguments 4651cb0ef41Sopenharmony_ci * is insignificant. This is an important property for sorting the 4661cb0ef41Sopenharmony_ci * list (when the list is preprocessed into binary form) and for 4671cb0ef41Sopenharmony_ci * performing binary searches on it at run time. 4681cb0ef41Sopenharmony_ci * 4691cb0ef41Sopenharmony_ci * @param name1 a converter name or alias, zero-terminated 4701cb0ef41Sopenharmony_ci * @param name2 a converter name or alias, zero-terminated 4711cb0ef41Sopenharmony_ci * @return 0 if the names match, or a negative value if the name1 4721cb0ef41Sopenharmony_ci * lexically precedes name2, or a positive value if the name1 4731cb0ef41Sopenharmony_ci * lexically follows name2. 4741cb0ef41Sopenharmony_ci * 4751cb0ef41Sopenharmony_ci * @see ucnv_io_stripForCompare 4761cb0ef41Sopenharmony_ci */ 4771cb0ef41Sopenharmony_ciU_CAPI int U_EXPORT2 4781cb0ef41Sopenharmony_ciucnv_compareNames(const char *name1, const char *name2) { 4791cb0ef41Sopenharmony_ci int rc; 4801cb0ef41Sopenharmony_ci uint8_t type, nextType; 4811cb0ef41Sopenharmony_ci char c1, c2; 4821cb0ef41Sopenharmony_ci UBool afterDigit1 = false, afterDigit2 = false; 4831cb0ef41Sopenharmony_ci 4841cb0ef41Sopenharmony_ci for (;;) { 4851cb0ef41Sopenharmony_ci while ((c1 = *name1++) != 0) { 4861cb0ef41Sopenharmony_ci type = GET_CHAR_TYPE(c1); 4871cb0ef41Sopenharmony_ci switch (type) { 4881cb0ef41Sopenharmony_ci case UIGNORE: 4891cb0ef41Sopenharmony_ci afterDigit1 = false; 4901cb0ef41Sopenharmony_ci continue; /* ignore all but letters and digits */ 4911cb0ef41Sopenharmony_ci case ZERO: 4921cb0ef41Sopenharmony_ci if (!afterDigit1) { 4931cb0ef41Sopenharmony_ci nextType = GET_CHAR_TYPE(*name1); 4941cb0ef41Sopenharmony_ci if (nextType == ZERO || nextType == NONZERO) { 4951cb0ef41Sopenharmony_ci continue; /* ignore leading zero before another digit */ 4961cb0ef41Sopenharmony_ci } 4971cb0ef41Sopenharmony_ci } 4981cb0ef41Sopenharmony_ci break; 4991cb0ef41Sopenharmony_ci case NONZERO: 5001cb0ef41Sopenharmony_ci afterDigit1 = true; 5011cb0ef41Sopenharmony_ci break; 5021cb0ef41Sopenharmony_ci default: 5031cb0ef41Sopenharmony_ci c1 = (char)type; /* lowercased letter */ 5041cb0ef41Sopenharmony_ci afterDigit1 = false; 5051cb0ef41Sopenharmony_ci break; 5061cb0ef41Sopenharmony_ci } 5071cb0ef41Sopenharmony_ci break; /* deliver c1 */ 5081cb0ef41Sopenharmony_ci } 5091cb0ef41Sopenharmony_ci while ((c2 = *name2++) != 0) { 5101cb0ef41Sopenharmony_ci type = GET_CHAR_TYPE(c2); 5111cb0ef41Sopenharmony_ci switch (type) { 5121cb0ef41Sopenharmony_ci case UIGNORE: 5131cb0ef41Sopenharmony_ci afterDigit2 = false; 5141cb0ef41Sopenharmony_ci continue; /* ignore all but letters and digits */ 5151cb0ef41Sopenharmony_ci case ZERO: 5161cb0ef41Sopenharmony_ci if (!afterDigit2) { 5171cb0ef41Sopenharmony_ci nextType = GET_CHAR_TYPE(*name2); 5181cb0ef41Sopenharmony_ci if (nextType == ZERO || nextType == NONZERO) { 5191cb0ef41Sopenharmony_ci continue; /* ignore leading zero before another digit */ 5201cb0ef41Sopenharmony_ci } 5211cb0ef41Sopenharmony_ci } 5221cb0ef41Sopenharmony_ci break; 5231cb0ef41Sopenharmony_ci case NONZERO: 5241cb0ef41Sopenharmony_ci afterDigit2 = true; 5251cb0ef41Sopenharmony_ci break; 5261cb0ef41Sopenharmony_ci default: 5271cb0ef41Sopenharmony_ci c2 = (char)type; /* lowercased letter */ 5281cb0ef41Sopenharmony_ci afterDigit2 = false; 5291cb0ef41Sopenharmony_ci break; 5301cb0ef41Sopenharmony_ci } 5311cb0ef41Sopenharmony_ci break; /* deliver c2 */ 5321cb0ef41Sopenharmony_ci } 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci /* If we reach the ends of both strings then they match */ 5351cb0ef41Sopenharmony_ci if ((c1|c2)==0) { 5361cb0ef41Sopenharmony_ci return 0; 5371cb0ef41Sopenharmony_ci } 5381cb0ef41Sopenharmony_ci 5391cb0ef41Sopenharmony_ci /* Case-insensitive comparison */ 5401cb0ef41Sopenharmony_ci rc = (int)(unsigned char)c1 - (int)(unsigned char)c2; 5411cb0ef41Sopenharmony_ci if (rc != 0) { 5421cb0ef41Sopenharmony_ci return rc; 5431cb0ef41Sopenharmony_ci } 5441cb0ef41Sopenharmony_ci } 5451cb0ef41Sopenharmony_ci} 5461cb0ef41Sopenharmony_ci 5471cb0ef41Sopenharmony_ci/* 5481cb0ef41Sopenharmony_ci * search for an alias 5491cb0ef41Sopenharmony_ci * return the converter number index for gConverterList 5501cb0ef41Sopenharmony_ci */ 5511cb0ef41Sopenharmony_cistatic inline uint32_t 5521cb0ef41Sopenharmony_cifindConverter(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) { 5531cb0ef41Sopenharmony_ci uint32_t mid, start, limit; 5541cb0ef41Sopenharmony_ci uint32_t lastMid; 5551cb0ef41Sopenharmony_ci int result; 5561cb0ef41Sopenharmony_ci int isUnnormalized = (gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED); 5571cb0ef41Sopenharmony_ci char strippedName[UCNV_MAX_CONVERTER_NAME_LENGTH]; 5581cb0ef41Sopenharmony_ci 5591cb0ef41Sopenharmony_ci if (!isUnnormalized) { 5601cb0ef41Sopenharmony_ci if (uprv_strlen(alias) >= UCNV_MAX_CONVERTER_NAME_LENGTH) { 5611cb0ef41Sopenharmony_ci *pErrorCode = U_BUFFER_OVERFLOW_ERROR; 5621cb0ef41Sopenharmony_ci return UINT32_MAX; 5631cb0ef41Sopenharmony_ci } 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci /* Lower case and remove ignoreable characters. */ 5661cb0ef41Sopenharmony_ci ucnv_io_stripForCompare(strippedName, alias); 5671cb0ef41Sopenharmony_ci alias = strippedName; 5681cb0ef41Sopenharmony_ci } 5691cb0ef41Sopenharmony_ci 5701cb0ef41Sopenharmony_ci /* do a binary search for the alias */ 5711cb0ef41Sopenharmony_ci start = 0; 5721cb0ef41Sopenharmony_ci limit = gMainTable.untaggedConvArraySize; 5731cb0ef41Sopenharmony_ci mid = limit; 5741cb0ef41Sopenharmony_ci lastMid = UINT32_MAX; 5751cb0ef41Sopenharmony_ci 5761cb0ef41Sopenharmony_ci for (;;) { 5771cb0ef41Sopenharmony_ci mid = (uint32_t)((start + limit) / 2); 5781cb0ef41Sopenharmony_ci if (lastMid == mid) { /* Have we moved? */ 5791cb0ef41Sopenharmony_ci break; /* We haven't moved, and it wasn't found. */ 5801cb0ef41Sopenharmony_ci } 5811cb0ef41Sopenharmony_ci lastMid = mid; 5821cb0ef41Sopenharmony_ci if (isUnnormalized) { 5831cb0ef41Sopenharmony_ci result = ucnv_compareNames(alias, GET_STRING(gMainTable.aliasList[mid])); 5841cb0ef41Sopenharmony_ci } 5851cb0ef41Sopenharmony_ci else { 5861cb0ef41Sopenharmony_ci result = uprv_strcmp(alias, GET_NORMALIZED_STRING(gMainTable.aliasList[mid])); 5871cb0ef41Sopenharmony_ci } 5881cb0ef41Sopenharmony_ci 5891cb0ef41Sopenharmony_ci if (result < 0) { 5901cb0ef41Sopenharmony_ci limit = mid; 5911cb0ef41Sopenharmony_ci } else if (result > 0) { 5921cb0ef41Sopenharmony_ci start = mid; 5931cb0ef41Sopenharmony_ci } else { 5941cb0ef41Sopenharmony_ci /* Since the gencnval tool folds duplicates into one entry, 5951cb0ef41Sopenharmony_ci * this alias in gAliasList is unique, but different standards 5961cb0ef41Sopenharmony_ci * may map an alias to different converters. 5971cb0ef41Sopenharmony_ci */ 5981cb0ef41Sopenharmony_ci if (gMainTable.untaggedConvArray[mid] & UCNV_AMBIGUOUS_ALIAS_MAP_BIT) { 5991cb0ef41Sopenharmony_ci *pErrorCode = U_AMBIGUOUS_ALIAS_WARNING; 6001cb0ef41Sopenharmony_ci } 6011cb0ef41Sopenharmony_ci /* State whether the canonical converter name contains an option. 6021cb0ef41Sopenharmony_ci This information is contained in this list in order to maintain backward & forward compatibility. */ 6031cb0ef41Sopenharmony_ci if (containsOption) { 6041cb0ef41Sopenharmony_ci UBool containsCnvOptionInfo = (UBool)gMainTable.optionTable->containsCnvOptionInfo; 6051cb0ef41Sopenharmony_ci *containsOption = (UBool)((containsCnvOptionInfo 6061cb0ef41Sopenharmony_ci && ((gMainTable.untaggedConvArray[mid] & UCNV_CONTAINS_OPTION_BIT) != 0)) 6071cb0ef41Sopenharmony_ci || !containsCnvOptionInfo); 6081cb0ef41Sopenharmony_ci } 6091cb0ef41Sopenharmony_ci return gMainTable.untaggedConvArray[mid] & UCNV_CONVERTER_INDEX_MASK; 6101cb0ef41Sopenharmony_ci } 6111cb0ef41Sopenharmony_ci } 6121cb0ef41Sopenharmony_ci 6131cb0ef41Sopenharmony_ci return UINT32_MAX; 6141cb0ef41Sopenharmony_ci} 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci/* 6171cb0ef41Sopenharmony_ci * Is this alias in this list? 6181cb0ef41Sopenharmony_ci * alias and listOffset should be non-nullptr. 6191cb0ef41Sopenharmony_ci */ 6201cb0ef41Sopenharmony_cistatic inline UBool 6211cb0ef41Sopenharmony_ciisAliasInList(const char *alias, uint32_t listOffset) { 6221cb0ef41Sopenharmony_ci if (listOffset) { 6231cb0ef41Sopenharmony_ci uint32_t currAlias; 6241cb0ef41Sopenharmony_ci uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 6251cb0ef41Sopenharmony_ci /* +1 to skip listCount */ 6261cb0ef41Sopenharmony_ci const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 6271cb0ef41Sopenharmony_ci for (currAlias = 0; currAlias < listCount; currAlias++) { 6281cb0ef41Sopenharmony_ci if (currList[currAlias] 6291cb0ef41Sopenharmony_ci && ucnv_compareNames(alias, GET_STRING(currList[currAlias]))==0) 6301cb0ef41Sopenharmony_ci { 6311cb0ef41Sopenharmony_ci return true; 6321cb0ef41Sopenharmony_ci } 6331cb0ef41Sopenharmony_ci } 6341cb0ef41Sopenharmony_ci } 6351cb0ef41Sopenharmony_ci return false; 6361cb0ef41Sopenharmony_ci} 6371cb0ef41Sopenharmony_ci 6381cb0ef41Sopenharmony_ci/* 6391cb0ef41Sopenharmony_ci * Search for an standard name of an alias (what is the default name 6401cb0ef41Sopenharmony_ci * that this standard uses?) 6411cb0ef41Sopenharmony_ci * return the listOffset for gTaggedAliasLists. If it's 0, 6421cb0ef41Sopenharmony_ci * the it couldn't be found, but the parameters are valid. 6431cb0ef41Sopenharmony_ci */ 6441cb0ef41Sopenharmony_cistatic uint32_t 6451cb0ef41Sopenharmony_cifindTaggedAliasListsOffset(const char *alias, const char *standard, UErrorCode *pErrorCode) { 6461cb0ef41Sopenharmony_ci uint32_t idx; 6471cb0ef41Sopenharmony_ci uint32_t listOffset; 6481cb0ef41Sopenharmony_ci uint32_t convNum; 6491cb0ef41Sopenharmony_ci UErrorCode myErr = U_ZERO_ERROR; 6501cb0ef41Sopenharmony_ci uint32_t tagNum = getTagNumber(standard); 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ci /* Make a quick guess. Hopefully they used a TR22 canonical alias. */ 6531cb0ef41Sopenharmony_ci convNum = findConverter(alias, nullptr, &myErr); 6541cb0ef41Sopenharmony_ci if (myErr != U_ZERO_ERROR) { 6551cb0ef41Sopenharmony_ci *pErrorCode = myErr; 6561cb0ef41Sopenharmony_ci } 6571cb0ef41Sopenharmony_ci 6581cb0ef41Sopenharmony_ci if (tagNum < (gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) && convNum < gMainTable.converterListSize) { 6591cb0ef41Sopenharmony_ci listOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + convNum]; 6601cb0ef41Sopenharmony_ci if (listOffset && gMainTable.taggedAliasLists[listOffset + 1]) { 6611cb0ef41Sopenharmony_ci return listOffset; 6621cb0ef41Sopenharmony_ci } 6631cb0ef41Sopenharmony_ci if (myErr == U_AMBIGUOUS_ALIAS_WARNING) { 6641cb0ef41Sopenharmony_ci /* Uh Oh! They used an ambiguous alias. 6651cb0ef41Sopenharmony_ci We have to search the whole swiss cheese starting 6661cb0ef41Sopenharmony_ci at the highest standard affinity. 6671cb0ef41Sopenharmony_ci This may take a while. 6681cb0ef41Sopenharmony_ci */ 6691cb0ef41Sopenharmony_ci for (idx = 0; idx < gMainTable.taggedAliasArraySize; idx++) { 6701cb0ef41Sopenharmony_ci listOffset = gMainTable.taggedAliasArray[idx]; 6711cb0ef41Sopenharmony_ci if (listOffset && isAliasInList(alias, listOffset)) { 6721cb0ef41Sopenharmony_ci uint32_t currTagNum = idx/gMainTable.converterListSize; 6731cb0ef41Sopenharmony_ci uint32_t currConvNum = (idx - currTagNum*gMainTable.converterListSize); 6741cb0ef41Sopenharmony_ci uint32_t tempListOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + currConvNum]; 6751cb0ef41Sopenharmony_ci if (tempListOffset && gMainTable.taggedAliasLists[tempListOffset + 1]) { 6761cb0ef41Sopenharmony_ci return tempListOffset; 6771cb0ef41Sopenharmony_ci } 6781cb0ef41Sopenharmony_ci /* else keep on looking */ 6791cb0ef41Sopenharmony_ci /* We could speed this up by starting on the next row 6801cb0ef41Sopenharmony_ci because an alias is unique per row, right now. 6811cb0ef41Sopenharmony_ci This would change if alias versioning appears. */ 6821cb0ef41Sopenharmony_ci } 6831cb0ef41Sopenharmony_ci } 6841cb0ef41Sopenharmony_ci /* The standard doesn't know about the alias */ 6851cb0ef41Sopenharmony_ci } 6861cb0ef41Sopenharmony_ci /* else no default name */ 6871cb0ef41Sopenharmony_ci return 0; 6881cb0ef41Sopenharmony_ci } 6891cb0ef41Sopenharmony_ci /* else converter or tag not found */ 6901cb0ef41Sopenharmony_ci 6911cb0ef41Sopenharmony_ci return UINT32_MAX; 6921cb0ef41Sopenharmony_ci} 6931cb0ef41Sopenharmony_ci 6941cb0ef41Sopenharmony_ci/* Return the canonical name */ 6951cb0ef41Sopenharmony_cistatic uint32_t 6961cb0ef41Sopenharmony_cifindTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErrorCode) { 6971cb0ef41Sopenharmony_ci uint32_t idx; 6981cb0ef41Sopenharmony_ci uint32_t listOffset; 6991cb0ef41Sopenharmony_ci uint32_t convNum; 7001cb0ef41Sopenharmony_ci UErrorCode myErr = U_ZERO_ERROR; 7011cb0ef41Sopenharmony_ci uint32_t tagNum = getTagNumber(standard); 7021cb0ef41Sopenharmony_ci 7031cb0ef41Sopenharmony_ci /* Make a quick guess. Hopefully they used a TR22 canonical alias. */ 7041cb0ef41Sopenharmony_ci convNum = findConverter(alias, nullptr, &myErr); 7051cb0ef41Sopenharmony_ci if (myErr != U_ZERO_ERROR) { 7061cb0ef41Sopenharmony_ci *pErrorCode = myErr; 7071cb0ef41Sopenharmony_ci } 7081cb0ef41Sopenharmony_ci 7091cb0ef41Sopenharmony_ci if (tagNum < (gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) && convNum < gMainTable.converterListSize) { 7101cb0ef41Sopenharmony_ci listOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + convNum]; 7111cb0ef41Sopenharmony_ci if (listOffset && isAliasInList(alias, listOffset)) { 7121cb0ef41Sopenharmony_ci return convNum; 7131cb0ef41Sopenharmony_ci } 7141cb0ef41Sopenharmony_ci if (myErr == U_AMBIGUOUS_ALIAS_WARNING) { 7151cb0ef41Sopenharmony_ci /* Uh Oh! They used an ambiguous alias. 7161cb0ef41Sopenharmony_ci We have to search one slice of the swiss cheese. 7171cb0ef41Sopenharmony_ci We search only in the requested tag, not the whole thing. 7181cb0ef41Sopenharmony_ci This may take a while. 7191cb0ef41Sopenharmony_ci */ 7201cb0ef41Sopenharmony_ci uint32_t convStart = (tagNum)*gMainTable.converterListSize; 7211cb0ef41Sopenharmony_ci uint32_t convLimit = (tagNum+1)*gMainTable.converterListSize; 7221cb0ef41Sopenharmony_ci for (idx = convStart; idx < convLimit; idx++) { 7231cb0ef41Sopenharmony_ci listOffset = gMainTable.taggedAliasArray[idx]; 7241cb0ef41Sopenharmony_ci if (listOffset && isAliasInList(alias, listOffset)) { 7251cb0ef41Sopenharmony_ci return idx-convStart; 7261cb0ef41Sopenharmony_ci } 7271cb0ef41Sopenharmony_ci } 7281cb0ef41Sopenharmony_ci /* The standard doesn't know about the alias */ 7291cb0ef41Sopenharmony_ci } 7301cb0ef41Sopenharmony_ci /* else no canonical name */ 7311cb0ef41Sopenharmony_ci } 7321cb0ef41Sopenharmony_ci /* else converter or tag not found */ 7331cb0ef41Sopenharmony_ci 7341cb0ef41Sopenharmony_ci return UINT32_MAX; 7351cb0ef41Sopenharmony_ci} 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_ciU_CAPI const char * 7381cb0ef41Sopenharmony_ciucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) { 7391cb0ef41Sopenharmony_ci const char *aliasTmp = alias; 7401cb0ef41Sopenharmony_ci int32_t i = 0; 7411cb0ef41Sopenharmony_ci for (i = 0; i < 2; i++) { 7421cb0ef41Sopenharmony_ci if (i == 1) { 7431cb0ef41Sopenharmony_ci /* 7441cb0ef41Sopenharmony_ci * After the first unsuccess converter lookup, check to see if 7451cb0ef41Sopenharmony_ci * the name begins with 'x-'. If it does, strip it off and try 7461cb0ef41Sopenharmony_ci * again. This behaviour is similar to how ICU4J does it. 7471cb0ef41Sopenharmony_ci */ 7481cb0ef41Sopenharmony_ci if (aliasTmp[0] == 'x' && aliasTmp[1] == '-') { 7491cb0ef41Sopenharmony_ci aliasTmp = aliasTmp+2; 7501cb0ef41Sopenharmony_ci } else { 7511cb0ef41Sopenharmony_ci break; 7521cb0ef41Sopenharmony_ci } 7531cb0ef41Sopenharmony_ci } 7541cb0ef41Sopenharmony_ci if(haveAliasData(pErrorCode) && isAlias(aliasTmp, pErrorCode)) { 7551cb0ef41Sopenharmony_ci uint32_t convNum = findConverter(aliasTmp, containsOption, pErrorCode); 7561cb0ef41Sopenharmony_ci if (convNum < gMainTable.converterListSize) { 7571cb0ef41Sopenharmony_ci return GET_STRING(gMainTable.converterList[convNum]); 7581cb0ef41Sopenharmony_ci } 7591cb0ef41Sopenharmony_ci /* else converter not found */ 7601cb0ef41Sopenharmony_ci } else { 7611cb0ef41Sopenharmony_ci break; 7621cb0ef41Sopenharmony_ci } 7631cb0ef41Sopenharmony_ci } 7641cb0ef41Sopenharmony_ci 7651cb0ef41Sopenharmony_ci return nullptr; 7661cb0ef41Sopenharmony_ci} 7671cb0ef41Sopenharmony_ci 7681cb0ef41Sopenharmony_ciU_CDECL_BEGIN 7691cb0ef41Sopenharmony_ci 7701cb0ef41Sopenharmony_ci 7711cb0ef41Sopenharmony_cistatic int32_t U_CALLCONV 7721cb0ef41Sopenharmony_ciucnv_io_countStandardAliases(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 7731cb0ef41Sopenharmony_ci int32_t value = 0; 7741cb0ef41Sopenharmony_ci UAliasContext *myContext = (UAliasContext *)(enumerator->context); 7751cb0ef41Sopenharmony_ci uint32_t listOffset = myContext->listOffset; 7761cb0ef41Sopenharmony_ci 7771cb0ef41Sopenharmony_ci if (listOffset) { 7781cb0ef41Sopenharmony_ci value = gMainTable.taggedAliasLists[listOffset]; 7791cb0ef41Sopenharmony_ci } 7801cb0ef41Sopenharmony_ci return value; 7811cb0ef41Sopenharmony_ci} 7821cb0ef41Sopenharmony_ci 7831cb0ef41Sopenharmony_cistatic const char * U_CALLCONV 7841cb0ef41Sopenharmony_ciucnv_io_nextStandardAliases(UEnumeration *enumerator, 7851cb0ef41Sopenharmony_ci int32_t* resultLength, 7861cb0ef41Sopenharmony_ci UErrorCode * /*pErrorCode*/) 7871cb0ef41Sopenharmony_ci{ 7881cb0ef41Sopenharmony_ci UAliasContext *myContext = (UAliasContext *)(enumerator->context); 7891cb0ef41Sopenharmony_ci uint32_t listOffset = myContext->listOffset; 7901cb0ef41Sopenharmony_ci 7911cb0ef41Sopenharmony_ci if (listOffset) { 7921cb0ef41Sopenharmony_ci uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 7931cb0ef41Sopenharmony_ci const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 7941cb0ef41Sopenharmony_ci 7951cb0ef41Sopenharmony_ci if (myContext->listIdx < listCount) { 7961cb0ef41Sopenharmony_ci const char *myStr = GET_STRING(currList[myContext->listIdx++]); 7971cb0ef41Sopenharmony_ci if (resultLength) { 7981cb0ef41Sopenharmony_ci *resultLength = (int32_t)uprv_strlen(myStr); 7991cb0ef41Sopenharmony_ci } 8001cb0ef41Sopenharmony_ci return myStr; 8011cb0ef41Sopenharmony_ci } 8021cb0ef41Sopenharmony_ci } 8031cb0ef41Sopenharmony_ci /* Either we accessed a zero length list, or we enumerated too far. */ 8041cb0ef41Sopenharmony_ci if (resultLength) { 8051cb0ef41Sopenharmony_ci *resultLength = 0; 8061cb0ef41Sopenharmony_ci } 8071cb0ef41Sopenharmony_ci return nullptr; 8081cb0ef41Sopenharmony_ci} 8091cb0ef41Sopenharmony_ci 8101cb0ef41Sopenharmony_cistatic void U_CALLCONV 8111cb0ef41Sopenharmony_ciucnv_io_resetStandardAliases(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 8121cb0ef41Sopenharmony_ci ((UAliasContext *)(enumerator->context))->listIdx = 0; 8131cb0ef41Sopenharmony_ci} 8141cb0ef41Sopenharmony_ci 8151cb0ef41Sopenharmony_cistatic void U_CALLCONV 8161cb0ef41Sopenharmony_ciucnv_io_closeUEnumeration(UEnumeration *enumerator) { 8171cb0ef41Sopenharmony_ci uprv_free(enumerator->context); 8181cb0ef41Sopenharmony_ci uprv_free(enumerator); 8191cb0ef41Sopenharmony_ci} 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ciU_CDECL_END 8221cb0ef41Sopenharmony_ci 8231cb0ef41Sopenharmony_ci/* Enumerate the aliases for the specified converter and standard tag */ 8241cb0ef41Sopenharmony_cistatic const UEnumeration gEnumAliases = { 8251cb0ef41Sopenharmony_ci nullptr, 8261cb0ef41Sopenharmony_ci nullptr, 8271cb0ef41Sopenharmony_ci ucnv_io_closeUEnumeration, 8281cb0ef41Sopenharmony_ci ucnv_io_countStandardAliases, 8291cb0ef41Sopenharmony_ci uenum_unextDefault, 8301cb0ef41Sopenharmony_ci ucnv_io_nextStandardAliases, 8311cb0ef41Sopenharmony_ci ucnv_io_resetStandardAliases 8321cb0ef41Sopenharmony_ci}; 8331cb0ef41Sopenharmony_ci 8341cb0ef41Sopenharmony_ciU_CAPI UEnumeration * U_EXPORT2 8351cb0ef41Sopenharmony_ciucnv_openStandardNames(const char *convName, 8361cb0ef41Sopenharmony_ci const char *standard, 8371cb0ef41Sopenharmony_ci UErrorCode *pErrorCode) 8381cb0ef41Sopenharmony_ci{ 8391cb0ef41Sopenharmony_ci UEnumeration *myEnum = nullptr; 8401cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode) && isAlias(convName, pErrorCode)) { 8411cb0ef41Sopenharmony_ci uint32_t listOffset = findTaggedAliasListsOffset(convName, standard, pErrorCode); 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_ci /* When listOffset == 0, we want to acknowledge that the 8441cb0ef41Sopenharmony_ci converter name and standard are okay, but there 8451cb0ef41Sopenharmony_ci is nothing to enumerate. */ 8461cb0ef41Sopenharmony_ci if (listOffset < gMainTable.taggedAliasListsSize) { 8471cb0ef41Sopenharmony_ci UAliasContext *myContext; 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_ci myEnum = static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))); 8501cb0ef41Sopenharmony_ci if (myEnum == nullptr) { 8511cb0ef41Sopenharmony_ci *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 8521cb0ef41Sopenharmony_ci return nullptr; 8531cb0ef41Sopenharmony_ci } 8541cb0ef41Sopenharmony_ci uprv_memcpy(myEnum, &gEnumAliases, sizeof(UEnumeration)); 8551cb0ef41Sopenharmony_ci myContext = static_cast<UAliasContext *>(uprv_malloc(sizeof(UAliasContext))); 8561cb0ef41Sopenharmony_ci if (myContext == nullptr) { 8571cb0ef41Sopenharmony_ci *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 8581cb0ef41Sopenharmony_ci uprv_free(myEnum); 8591cb0ef41Sopenharmony_ci return nullptr; 8601cb0ef41Sopenharmony_ci } 8611cb0ef41Sopenharmony_ci myContext->listOffset = listOffset; 8621cb0ef41Sopenharmony_ci myContext->listIdx = 0; 8631cb0ef41Sopenharmony_ci myEnum->context = myContext; 8641cb0ef41Sopenharmony_ci } 8651cb0ef41Sopenharmony_ci /* else converter or tag not found */ 8661cb0ef41Sopenharmony_ci } 8671cb0ef41Sopenharmony_ci return myEnum; 8681cb0ef41Sopenharmony_ci} 8691cb0ef41Sopenharmony_ci 8701cb0ef41Sopenharmony_cistatic uint16_t 8711cb0ef41Sopenharmony_ciucnv_io_countAliases(const char *alias, UErrorCode *pErrorCode) { 8721cb0ef41Sopenharmony_ci if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 8731cb0ef41Sopenharmony_ci uint32_t convNum = findConverter(alias, nullptr, pErrorCode); 8741cb0ef41Sopenharmony_ci if (convNum < gMainTable.converterListSize) { 8751cb0ef41Sopenharmony_ci /* tagListNum - 1 is the ALL tag */ 8761cb0ef41Sopenharmony_ci int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum]; 8771cb0ef41Sopenharmony_ci 8781cb0ef41Sopenharmony_ci if (listOffset) { 8791cb0ef41Sopenharmony_ci return gMainTable.taggedAliasLists[listOffset]; 8801cb0ef41Sopenharmony_ci } 8811cb0ef41Sopenharmony_ci /* else this shouldn't happen. internal program error */ 8821cb0ef41Sopenharmony_ci } 8831cb0ef41Sopenharmony_ci /* else converter not found */ 8841cb0ef41Sopenharmony_ci } 8851cb0ef41Sopenharmony_ci return 0; 8861cb0ef41Sopenharmony_ci} 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_cistatic uint16_t 8891cb0ef41Sopenharmony_ciucnv_io_getAliases(const char *alias, uint16_t start, const char **aliases, UErrorCode *pErrorCode) { 8901cb0ef41Sopenharmony_ci if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 8911cb0ef41Sopenharmony_ci uint32_t currAlias; 8921cb0ef41Sopenharmony_ci uint32_t convNum = findConverter(alias, nullptr, pErrorCode); 8931cb0ef41Sopenharmony_ci if (convNum < gMainTable.converterListSize) { 8941cb0ef41Sopenharmony_ci /* tagListNum - 1 is the ALL tag */ 8951cb0ef41Sopenharmony_ci int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum]; 8961cb0ef41Sopenharmony_ci 8971cb0ef41Sopenharmony_ci if (listOffset) { 8981cb0ef41Sopenharmony_ci uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 8991cb0ef41Sopenharmony_ci /* +1 to skip listCount */ 9001cb0ef41Sopenharmony_ci const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 9011cb0ef41Sopenharmony_ci 9021cb0ef41Sopenharmony_ci for (currAlias = start; currAlias < listCount; currAlias++) { 9031cb0ef41Sopenharmony_ci aliases[currAlias] = GET_STRING(currList[currAlias]); 9041cb0ef41Sopenharmony_ci } 9051cb0ef41Sopenharmony_ci } 9061cb0ef41Sopenharmony_ci /* else this shouldn't happen. internal program error */ 9071cb0ef41Sopenharmony_ci } 9081cb0ef41Sopenharmony_ci /* else converter not found */ 9091cb0ef41Sopenharmony_ci } 9101cb0ef41Sopenharmony_ci return 0; 9111cb0ef41Sopenharmony_ci} 9121cb0ef41Sopenharmony_ci 9131cb0ef41Sopenharmony_cistatic const char * 9141cb0ef41Sopenharmony_ciucnv_io_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) { 9151cb0ef41Sopenharmony_ci if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 9161cb0ef41Sopenharmony_ci uint32_t convNum = findConverter(alias, nullptr, pErrorCode); 9171cb0ef41Sopenharmony_ci if (convNum < gMainTable.converterListSize) { 9181cb0ef41Sopenharmony_ci /* tagListNum - 1 is the ALL tag */ 9191cb0ef41Sopenharmony_ci int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum]; 9201cb0ef41Sopenharmony_ci 9211cb0ef41Sopenharmony_ci if (listOffset) { 9221cb0ef41Sopenharmony_ci uint32_t listCount = gMainTable.taggedAliasLists[listOffset]; 9231cb0ef41Sopenharmony_ci /* +1 to skip listCount */ 9241cb0ef41Sopenharmony_ci const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 9251cb0ef41Sopenharmony_ci 9261cb0ef41Sopenharmony_ci if (n < listCount) { 9271cb0ef41Sopenharmony_ci return GET_STRING(currList[n]); 9281cb0ef41Sopenharmony_ci } 9291cb0ef41Sopenharmony_ci *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; 9301cb0ef41Sopenharmony_ci } 9311cb0ef41Sopenharmony_ci /* else this shouldn't happen. internal program error */ 9321cb0ef41Sopenharmony_ci } 9331cb0ef41Sopenharmony_ci /* else converter not found */ 9341cb0ef41Sopenharmony_ci } 9351cb0ef41Sopenharmony_ci return nullptr; 9361cb0ef41Sopenharmony_ci} 9371cb0ef41Sopenharmony_ci 9381cb0ef41Sopenharmony_cistatic uint16_t 9391cb0ef41Sopenharmony_ciucnv_io_countStandards(UErrorCode *pErrorCode) { 9401cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode)) { 9411cb0ef41Sopenharmony_ci /* Don't include the empty list */ 9421cb0ef41Sopenharmony_ci return (uint16_t)(gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS); 9431cb0ef41Sopenharmony_ci } 9441cb0ef41Sopenharmony_ci 9451cb0ef41Sopenharmony_ci return 0; 9461cb0ef41Sopenharmony_ci} 9471cb0ef41Sopenharmony_ci 9481cb0ef41Sopenharmony_ciU_CAPI const char * U_EXPORT2 9491cb0ef41Sopenharmony_ciucnv_getStandard(uint16_t n, UErrorCode *pErrorCode) { 9501cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode)) { 9511cb0ef41Sopenharmony_ci if (n < gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) { 9521cb0ef41Sopenharmony_ci return GET_STRING(gMainTable.tagList[n]); 9531cb0ef41Sopenharmony_ci } 9541cb0ef41Sopenharmony_ci *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; 9551cb0ef41Sopenharmony_ci } 9561cb0ef41Sopenharmony_ci 9571cb0ef41Sopenharmony_ci return nullptr; 9581cb0ef41Sopenharmony_ci} 9591cb0ef41Sopenharmony_ci 9601cb0ef41Sopenharmony_ciU_CAPI const char * U_EXPORT2 9611cb0ef41Sopenharmony_ciucnv_getStandardName(const char *alias, const char *standard, UErrorCode *pErrorCode) { 9621cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 9631cb0ef41Sopenharmony_ci uint32_t listOffset = findTaggedAliasListsOffset(alias, standard, pErrorCode); 9641cb0ef41Sopenharmony_ci 9651cb0ef41Sopenharmony_ci if (0 < listOffset && listOffset < gMainTable.taggedAliasListsSize) { 9661cb0ef41Sopenharmony_ci const uint16_t *currList = gMainTable.taggedAliasLists + listOffset + 1; 9671cb0ef41Sopenharmony_ci 9681cb0ef41Sopenharmony_ci /* Get the preferred name from this list */ 9691cb0ef41Sopenharmony_ci if (currList[0]) { 9701cb0ef41Sopenharmony_ci return GET_STRING(currList[0]); 9711cb0ef41Sopenharmony_ci } 9721cb0ef41Sopenharmony_ci /* else someone screwed up the alias table. */ 9731cb0ef41Sopenharmony_ci /* *pErrorCode = U_INVALID_FORMAT_ERROR */ 9741cb0ef41Sopenharmony_ci } 9751cb0ef41Sopenharmony_ci } 9761cb0ef41Sopenharmony_ci 9771cb0ef41Sopenharmony_ci return nullptr; 9781cb0ef41Sopenharmony_ci} 9791cb0ef41Sopenharmony_ci 9801cb0ef41Sopenharmony_ciU_CAPI uint16_t U_EXPORT2 9811cb0ef41Sopenharmony_ciucnv_countAliases(const char *alias, UErrorCode *pErrorCode) 9821cb0ef41Sopenharmony_ci{ 9831cb0ef41Sopenharmony_ci return ucnv_io_countAliases(alias, pErrorCode); 9841cb0ef41Sopenharmony_ci} 9851cb0ef41Sopenharmony_ci 9861cb0ef41Sopenharmony_ci 9871cb0ef41Sopenharmony_ciU_CAPI const char* U_EXPORT2 9881cb0ef41Sopenharmony_ciucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) 9891cb0ef41Sopenharmony_ci{ 9901cb0ef41Sopenharmony_ci return ucnv_io_getAlias(alias, n, pErrorCode); 9911cb0ef41Sopenharmony_ci} 9921cb0ef41Sopenharmony_ci 9931cb0ef41Sopenharmony_ciU_CAPI void U_EXPORT2 9941cb0ef41Sopenharmony_ciucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode) 9951cb0ef41Sopenharmony_ci{ 9961cb0ef41Sopenharmony_ci ucnv_io_getAliases(alias, 0, aliases, pErrorCode); 9971cb0ef41Sopenharmony_ci} 9981cb0ef41Sopenharmony_ci 9991cb0ef41Sopenharmony_ciU_CAPI uint16_t U_EXPORT2 10001cb0ef41Sopenharmony_ciucnv_countStandards() 10011cb0ef41Sopenharmony_ci{ 10021cb0ef41Sopenharmony_ci UErrorCode err = U_ZERO_ERROR; 10031cb0ef41Sopenharmony_ci return ucnv_io_countStandards(&err); 10041cb0ef41Sopenharmony_ci} 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_ciU_CAPI const char * U_EXPORT2 10071cb0ef41Sopenharmony_ciucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErrorCode) { 10081cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) { 10091cb0ef41Sopenharmony_ci uint32_t convNum = findTaggedConverterNum(alias, standard, pErrorCode); 10101cb0ef41Sopenharmony_ci 10111cb0ef41Sopenharmony_ci if (convNum < gMainTable.converterListSize) { 10121cb0ef41Sopenharmony_ci return GET_STRING(gMainTable.converterList[convNum]); 10131cb0ef41Sopenharmony_ci } 10141cb0ef41Sopenharmony_ci } 10151cb0ef41Sopenharmony_ci 10161cb0ef41Sopenharmony_ci return nullptr; 10171cb0ef41Sopenharmony_ci} 10181cb0ef41Sopenharmony_ci 10191cb0ef41Sopenharmony_ciU_CDECL_BEGIN 10201cb0ef41Sopenharmony_ci 10211cb0ef41Sopenharmony_ci 10221cb0ef41Sopenharmony_cistatic int32_t U_CALLCONV 10231cb0ef41Sopenharmony_ciucnv_io_countAllConverters(UEnumeration * /*enumerator*/, UErrorCode * /*pErrorCode*/) { 10241cb0ef41Sopenharmony_ci return gMainTable.converterListSize; 10251cb0ef41Sopenharmony_ci} 10261cb0ef41Sopenharmony_ci 10271cb0ef41Sopenharmony_cistatic const char * U_CALLCONV 10281cb0ef41Sopenharmony_ciucnv_io_nextAllConverters(UEnumeration *enumerator, 10291cb0ef41Sopenharmony_ci int32_t* resultLength, 10301cb0ef41Sopenharmony_ci UErrorCode * /*pErrorCode*/) 10311cb0ef41Sopenharmony_ci{ 10321cb0ef41Sopenharmony_ci uint16_t *myContext = (uint16_t *)(enumerator->context); 10331cb0ef41Sopenharmony_ci 10341cb0ef41Sopenharmony_ci if (*myContext < gMainTable.converterListSize) { 10351cb0ef41Sopenharmony_ci const char *myStr = GET_STRING(gMainTable.converterList[(*myContext)++]); 10361cb0ef41Sopenharmony_ci if (resultLength) { 10371cb0ef41Sopenharmony_ci *resultLength = (int32_t)uprv_strlen(myStr); 10381cb0ef41Sopenharmony_ci } 10391cb0ef41Sopenharmony_ci return myStr; 10401cb0ef41Sopenharmony_ci } 10411cb0ef41Sopenharmony_ci /* Either we accessed a zero length list, or we enumerated too far. */ 10421cb0ef41Sopenharmony_ci if (resultLength) { 10431cb0ef41Sopenharmony_ci *resultLength = 0; 10441cb0ef41Sopenharmony_ci } 10451cb0ef41Sopenharmony_ci return nullptr; 10461cb0ef41Sopenharmony_ci} 10471cb0ef41Sopenharmony_ci 10481cb0ef41Sopenharmony_cistatic void U_CALLCONV 10491cb0ef41Sopenharmony_ciucnv_io_resetAllConverters(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 10501cb0ef41Sopenharmony_ci *((uint16_t *)(enumerator->context)) = 0; 10511cb0ef41Sopenharmony_ci} 10521cb0ef41Sopenharmony_ciU_CDECL_END 10531cb0ef41Sopenharmony_cistatic const UEnumeration gEnumAllConverters = { 10541cb0ef41Sopenharmony_ci nullptr, 10551cb0ef41Sopenharmony_ci nullptr, 10561cb0ef41Sopenharmony_ci ucnv_io_closeUEnumeration, 10571cb0ef41Sopenharmony_ci ucnv_io_countAllConverters, 10581cb0ef41Sopenharmony_ci uenum_unextDefault, 10591cb0ef41Sopenharmony_ci ucnv_io_nextAllConverters, 10601cb0ef41Sopenharmony_ci ucnv_io_resetAllConverters 10611cb0ef41Sopenharmony_ci}; 10621cb0ef41Sopenharmony_ci 10631cb0ef41Sopenharmony_ciU_CAPI UEnumeration * U_EXPORT2 10641cb0ef41Sopenharmony_ciucnv_openAllNames(UErrorCode *pErrorCode) { 10651cb0ef41Sopenharmony_ci UEnumeration *myEnum = nullptr; 10661cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode)) { 10671cb0ef41Sopenharmony_ci uint16_t *myContext; 10681cb0ef41Sopenharmony_ci 10691cb0ef41Sopenharmony_ci myEnum = static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))); 10701cb0ef41Sopenharmony_ci if (myEnum == nullptr) { 10711cb0ef41Sopenharmony_ci *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 10721cb0ef41Sopenharmony_ci return nullptr; 10731cb0ef41Sopenharmony_ci } 10741cb0ef41Sopenharmony_ci uprv_memcpy(myEnum, &gEnumAllConverters, sizeof(UEnumeration)); 10751cb0ef41Sopenharmony_ci myContext = static_cast<uint16_t *>(uprv_malloc(sizeof(uint16_t))); 10761cb0ef41Sopenharmony_ci if (myContext == nullptr) { 10771cb0ef41Sopenharmony_ci *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 10781cb0ef41Sopenharmony_ci uprv_free(myEnum); 10791cb0ef41Sopenharmony_ci return nullptr; 10801cb0ef41Sopenharmony_ci } 10811cb0ef41Sopenharmony_ci *myContext = 0; 10821cb0ef41Sopenharmony_ci myEnum->context = myContext; 10831cb0ef41Sopenharmony_ci } 10841cb0ef41Sopenharmony_ci return myEnum; 10851cb0ef41Sopenharmony_ci} 10861cb0ef41Sopenharmony_ci 10871cb0ef41Sopenharmony_ciU_CAPI uint16_t 10881cb0ef41Sopenharmony_ciucnv_io_countKnownConverters(UErrorCode *pErrorCode) { 10891cb0ef41Sopenharmony_ci if (haveAliasData(pErrorCode)) { 10901cb0ef41Sopenharmony_ci return (uint16_t)gMainTable.converterListSize; 10911cb0ef41Sopenharmony_ci } 10921cb0ef41Sopenharmony_ci return 0; 10931cb0ef41Sopenharmony_ci} 10941cb0ef41Sopenharmony_ci 10951cb0ef41Sopenharmony_ci/* alias table swapping ----------------------------------------------------- */ 10961cb0ef41Sopenharmony_ci 10971cb0ef41Sopenharmony_ciU_CDECL_BEGIN 10981cb0ef41Sopenharmony_ci 10991cb0ef41Sopenharmony_citypedef char * U_CALLCONV StripForCompareFn(char *dst, const char *name); 11001cb0ef41Sopenharmony_ciU_CDECL_END 11011cb0ef41Sopenharmony_ci 11021cb0ef41Sopenharmony_ci 11031cb0ef41Sopenharmony_ci/* 11041cb0ef41Sopenharmony_ci * row of a temporary array 11051cb0ef41Sopenharmony_ci * 11061cb0ef41Sopenharmony_ci * gets platform-endian charset string indexes and sorting indexes; 11071cb0ef41Sopenharmony_ci * after sorting this array by strings, the actual arrays are permutated 11081cb0ef41Sopenharmony_ci * according to the sorting indexes 11091cb0ef41Sopenharmony_ci */ 11101cb0ef41Sopenharmony_citypedef struct TempRow { 11111cb0ef41Sopenharmony_ci uint16_t strIndex, sortIndex; 11121cb0ef41Sopenharmony_ci} TempRow; 11131cb0ef41Sopenharmony_ci 11141cb0ef41Sopenharmony_citypedef struct TempAliasTable { 11151cb0ef41Sopenharmony_ci const char *chars; 11161cb0ef41Sopenharmony_ci TempRow *rows; 11171cb0ef41Sopenharmony_ci uint16_t *resort; 11181cb0ef41Sopenharmony_ci StripForCompareFn *stripForCompare; 11191cb0ef41Sopenharmony_ci} TempAliasTable; 11201cb0ef41Sopenharmony_ci 11211cb0ef41Sopenharmony_cienum { 11221cb0ef41Sopenharmony_ci STACK_ROW_CAPACITY=500 11231cb0ef41Sopenharmony_ci}; 11241cb0ef41Sopenharmony_ci 11251cb0ef41Sopenharmony_cistatic int32_t U_CALLCONV 11261cb0ef41Sopenharmony_ciio_compareRows(const void *context, const void *left, const void *right) { 11271cb0ef41Sopenharmony_ci char strippedLeft[UCNV_MAX_CONVERTER_NAME_LENGTH], 11281cb0ef41Sopenharmony_ci strippedRight[UCNV_MAX_CONVERTER_NAME_LENGTH]; 11291cb0ef41Sopenharmony_ci 11301cb0ef41Sopenharmony_ci TempAliasTable *tempTable=(TempAliasTable *)context; 11311cb0ef41Sopenharmony_ci const char *chars=tempTable->chars; 11321cb0ef41Sopenharmony_ci 11331cb0ef41Sopenharmony_ci return (int32_t)uprv_strcmp(tempTable->stripForCompare(strippedLeft, chars+2*((const TempRow *)left)->strIndex), 11341cb0ef41Sopenharmony_ci tempTable->stripForCompare(strippedRight, chars+2*((const TempRow *)right)->strIndex)); 11351cb0ef41Sopenharmony_ci} 11361cb0ef41Sopenharmony_ci 11371cb0ef41Sopenharmony_ciU_CAPI int32_t U_EXPORT2 11381cb0ef41Sopenharmony_ciucnv_swapAliases(const UDataSwapper *ds, 11391cb0ef41Sopenharmony_ci const void *inData, int32_t length, void *outData, 11401cb0ef41Sopenharmony_ci UErrorCode *pErrorCode) { 11411cb0ef41Sopenharmony_ci const UDataInfo *pInfo; 11421cb0ef41Sopenharmony_ci int32_t headerSize; 11431cb0ef41Sopenharmony_ci 11441cb0ef41Sopenharmony_ci const uint16_t *inTable; 11451cb0ef41Sopenharmony_ci const uint32_t *inSectionSizes; 11461cb0ef41Sopenharmony_ci uint32_t toc[offsetsCount]; 11471cb0ef41Sopenharmony_ci uint32_t offsets[offsetsCount]; /* 16-bit-addressed offsets from inTable/outTable */ 11481cb0ef41Sopenharmony_ci uint32_t i, count, tocLength, topOffset; 11491cb0ef41Sopenharmony_ci 11501cb0ef41Sopenharmony_ci TempRow rows[STACK_ROW_CAPACITY]; 11511cb0ef41Sopenharmony_ci uint16_t resort[STACK_ROW_CAPACITY]; 11521cb0ef41Sopenharmony_ci TempAliasTable tempTable; 11531cb0ef41Sopenharmony_ci 11541cb0ef41Sopenharmony_ci /* udata_swapDataHeader checks the arguments */ 11551cb0ef41Sopenharmony_ci headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 11561cb0ef41Sopenharmony_ci if(pErrorCode==nullptr || U_FAILURE(*pErrorCode)) { 11571cb0ef41Sopenharmony_ci return 0; 11581cb0ef41Sopenharmony_ci } 11591cb0ef41Sopenharmony_ci 11601cb0ef41Sopenharmony_ci /* check data format and format version */ 11611cb0ef41Sopenharmony_ci pInfo=(const UDataInfo *)((const char *)inData+4); 11621cb0ef41Sopenharmony_ci if(!( 11631cb0ef41Sopenharmony_ci pInfo->dataFormat[0]==0x43 && /* dataFormat="CvAl" */ 11641cb0ef41Sopenharmony_ci pInfo->dataFormat[1]==0x76 && 11651cb0ef41Sopenharmony_ci pInfo->dataFormat[2]==0x41 && 11661cb0ef41Sopenharmony_ci pInfo->dataFormat[3]==0x6c && 11671cb0ef41Sopenharmony_ci pInfo->formatVersion[0]==3 11681cb0ef41Sopenharmony_ci )) { 11691cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases(): data format %02x.%02x.%02x.%02x (format version %02x) is not an alias table\n", 11701cb0ef41Sopenharmony_ci pInfo->dataFormat[0], pInfo->dataFormat[1], 11711cb0ef41Sopenharmony_ci pInfo->dataFormat[2], pInfo->dataFormat[3], 11721cb0ef41Sopenharmony_ci pInfo->formatVersion[0]); 11731cb0ef41Sopenharmony_ci *pErrorCode=U_UNSUPPORTED_ERROR; 11741cb0ef41Sopenharmony_ci return 0; 11751cb0ef41Sopenharmony_ci } 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_ci /* an alias table must contain at least the table of contents array */ 11781cb0ef41Sopenharmony_ci if(length>=0 && (length-headerSize)<4*(1+minTocLength)) { 11791cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases(): too few bytes (%d after header) for an alias table\n", 11801cb0ef41Sopenharmony_ci length-headerSize); 11811cb0ef41Sopenharmony_ci *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 11821cb0ef41Sopenharmony_ci return 0; 11831cb0ef41Sopenharmony_ci } 11841cb0ef41Sopenharmony_ci 11851cb0ef41Sopenharmony_ci inSectionSizes=(const uint32_t *)((const char *)inData+headerSize); 11861cb0ef41Sopenharmony_ci inTable=(const uint16_t *)inSectionSizes; 11871cb0ef41Sopenharmony_ci uprv_memset(toc, 0, sizeof(toc)); 11881cb0ef41Sopenharmony_ci toc[tocLengthIndex]=tocLength=ds->readUInt32(inSectionSizes[tocLengthIndex]); 11891cb0ef41Sopenharmony_ci if(tocLength<minTocLength || offsetsCount<=tocLength) { 11901cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases(): table of contents contains unsupported number of sections (%u sections)\n", tocLength); 11911cb0ef41Sopenharmony_ci *pErrorCode=U_INVALID_FORMAT_ERROR; 11921cb0ef41Sopenharmony_ci return 0; 11931cb0ef41Sopenharmony_ci } 11941cb0ef41Sopenharmony_ci 11951cb0ef41Sopenharmony_ci /* read the known part of the table of contents */ 11961cb0ef41Sopenharmony_ci for(i=converterListIndex; i<=tocLength; ++i) { 11971cb0ef41Sopenharmony_ci toc[i]=ds->readUInt32(inSectionSizes[i]); 11981cb0ef41Sopenharmony_ci } 11991cb0ef41Sopenharmony_ci 12001cb0ef41Sopenharmony_ci /* compute offsets */ 12011cb0ef41Sopenharmony_ci uprv_memset(offsets, 0, sizeof(offsets)); 12021cb0ef41Sopenharmony_ci offsets[converterListIndex]=2*(1+tocLength); /* count two 16-bit units per toc entry */ 12031cb0ef41Sopenharmony_ci for(i=tagListIndex; i<=tocLength; ++i) { 12041cb0ef41Sopenharmony_ci offsets[i]=offsets[i-1]+toc[i-1]; 12051cb0ef41Sopenharmony_ci } 12061cb0ef41Sopenharmony_ci 12071cb0ef41Sopenharmony_ci /* compute the overall size of the after-header data, in numbers of 16-bit units */ 12081cb0ef41Sopenharmony_ci topOffset=offsets[i-1]+toc[i-1]; 12091cb0ef41Sopenharmony_ci 12101cb0ef41Sopenharmony_ci if(length>=0) { 12111cb0ef41Sopenharmony_ci uint16_t *outTable; 12121cb0ef41Sopenharmony_ci const uint16_t *p, *p2; 12131cb0ef41Sopenharmony_ci uint16_t *q, *q2; 12141cb0ef41Sopenharmony_ci uint16_t oldIndex; 12151cb0ef41Sopenharmony_ci 12161cb0ef41Sopenharmony_ci if((length-headerSize)<(2*(int32_t)topOffset)) { 12171cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases(): too few bytes (%d after header) for an alias table\n", 12181cb0ef41Sopenharmony_ci length-headerSize); 12191cb0ef41Sopenharmony_ci *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 12201cb0ef41Sopenharmony_ci return 0; 12211cb0ef41Sopenharmony_ci } 12221cb0ef41Sopenharmony_ci 12231cb0ef41Sopenharmony_ci outTable=(uint16_t *)((char *)outData+headerSize); 12241cb0ef41Sopenharmony_ci 12251cb0ef41Sopenharmony_ci /* swap the entire table of contents */ 12261cb0ef41Sopenharmony_ci ds->swapArray32(ds, inTable, 4*(1+tocLength), outTable, pErrorCode); 12271cb0ef41Sopenharmony_ci 12281cb0ef41Sopenharmony_ci /* swap unormalized strings & normalized strings */ 12291cb0ef41Sopenharmony_ci ds->swapInvChars(ds, inTable+offsets[stringTableIndex], 2*(int32_t)(toc[stringTableIndex]+toc[normalizedStringTableIndex]), 12301cb0ef41Sopenharmony_ci outTable+offsets[stringTableIndex], pErrorCode); 12311cb0ef41Sopenharmony_ci if(U_FAILURE(*pErrorCode)) { 12321cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases().swapInvChars(charset names) failed\n"); 12331cb0ef41Sopenharmony_ci return 0; 12341cb0ef41Sopenharmony_ci } 12351cb0ef41Sopenharmony_ci 12361cb0ef41Sopenharmony_ci if(ds->inCharset==ds->outCharset) { 12371cb0ef41Sopenharmony_ci /* no need to sort, just swap all 16-bit values together */ 12381cb0ef41Sopenharmony_ci ds->swapArray16(ds, 12391cb0ef41Sopenharmony_ci inTable+offsets[converterListIndex], 12401cb0ef41Sopenharmony_ci 2*(int32_t)(offsets[stringTableIndex]-offsets[converterListIndex]), 12411cb0ef41Sopenharmony_ci outTable+offsets[converterListIndex], 12421cb0ef41Sopenharmony_ci pErrorCode); 12431cb0ef41Sopenharmony_ci } else { 12441cb0ef41Sopenharmony_ci /* allocate the temporary table for sorting */ 12451cb0ef41Sopenharmony_ci count=toc[aliasListIndex]; 12461cb0ef41Sopenharmony_ci 12471cb0ef41Sopenharmony_ci tempTable.chars=(const char *)(outTable+offsets[stringTableIndex]); /* sort by outCharset */ 12481cb0ef41Sopenharmony_ci 12491cb0ef41Sopenharmony_ci if(count<=STACK_ROW_CAPACITY) { 12501cb0ef41Sopenharmony_ci tempTable.rows=rows; 12511cb0ef41Sopenharmony_ci tempTable.resort=resort; 12521cb0ef41Sopenharmony_ci } else { 12531cb0ef41Sopenharmony_ci tempTable.rows=(TempRow *)uprv_malloc(count*sizeof(TempRow)+count*2); 12541cb0ef41Sopenharmony_ci if(tempTable.rows==nullptr) { 12551cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases(): unable to allocate memory for sorting tables (max length: %u)\n", 12561cb0ef41Sopenharmony_ci count); 12571cb0ef41Sopenharmony_ci *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 12581cb0ef41Sopenharmony_ci return 0; 12591cb0ef41Sopenharmony_ci } 12601cb0ef41Sopenharmony_ci tempTable.resort=(uint16_t *)(tempTable.rows+count); 12611cb0ef41Sopenharmony_ci } 12621cb0ef41Sopenharmony_ci 12631cb0ef41Sopenharmony_ci if(ds->outCharset==U_ASCII_FAMILY) { 12641cb0ef41Sopenharmony_ci tempTable.stripForCompare=ucnv_io_stripASCIIForCompare; 12651cb0ef41Sopenharmony_ci } else /* U_EBCDIC_FAMILY */ { 12661cb0ef41Sopenharmony_ci tempTable.stripForCompare=ucnv_io_stripEBCDICForCompare; 12671cb0ef41Sopenharmony_ci } 12681cb0ef41Sopenharmony_ci 12691cb0ef41Sopenharmony_ci /* 12701cb0ef41Sopenharmony_ci * Sort unique aliases+mapped names. 12711cb0ef41Sopenharmony_ci * 12721cb0ef41Sopenharmony_ci * We need to sort the list again by outCharset strings because they 12731cb0ef41Sopenharmony_ci * sort differently for different charset families. 12741cb0ef41Sopenharmony_ci * First we set up a temporary table with the string indexes and 12751cb0ef41Sopenharmony_ci * sorting indexes and sort that. 12761cb0ef41Sopenharmony_ci * Then we permutate and copy/swap the actual values. 12771cb0ef41Sopenharmony_ci */ 12781cb0ef41Sopenharmony_ci p=inTable+offsets[aliasListIndex]; 12791cb0ef41Sopenharmony_ci q=outTable+offsets[aliasListIndex]; 12801cb0ef41Sopenharmony_ci 12811cb0ef41Sopenharmony_ci p2=inTable+offsets[untaggedConvArrayIndex]; 12821cb0ef41Sopenharmony_ci q2=outTable+offsets[untaggedConvArrayIndex]; 12831cb0ef41Sopenharmony_ci 12841cb0ef41Sopenharmony_ci for(i=0; i<count; ++i) { 12851cb0ef41Sopenharmony_ci tempTable.rows[i].strIndex=ds->readUInt16(p[i]); 12861cb0ef41Sopenharmony_ci tempTable.rows[i].sortIndex=(uint16_t)i; 12871cb0ef41Sopenharmony_ci } 12881cb0ef41Sopenharmony_ci 12891cb0ef41Sopenharmony_ci uprv_sortArray(tempTable.rows, (int32_t)count, sizeof(TempRow), 12901cb0ef41Sopenharmony_ci io_compareRows, &tempTable, 12911cb0ef41Sopenharmony_ci false, pErrorCode); 12921cb0ef41Sopenharmony_ci 12931cb0ef41Sopenharmony_ci if(U_SUCCESS(*pErrorCode)) { 12941cb0ef41Sopenharmony_ci /* copy/swap/permutate items */ 12951cb0ef41Sopenharmony_ci if(p!=q) { 12961cb0ef41Sopenharmony_ci for(i=0; i<count; ++i) { 12971cb0ef41Sopenharmony_ci oldIndex=tempTable.rows[i].sortIndex; 12981cb0ef41Sopenharmony_ci ds->swapArray16(ds, p+oldIndex, 2, q+i, pErrorCode); 12991cb0ef41Sopenharmony_ci ds->swapArray16(ds, p2+oldIndex, 2, q2+i, pErrorCode); 13001cb0ef41Sopenharmony_ci } 13011cb0ef41Sopenharmony_ci } else { 13021cb0ef41Sopenharmony_ci /* 13031cb0ef41Sopenharmony_ci * If we swap in-place, then the permutation must use another 13041cb0ef41Sopenharmony_ci * temporary array (tempTable.resort) 13051cb0ef41Sopenharmony_ci * before the results are copied to the outBundle. 13061cb0ef41Sopenharmony_ci */ 13071cb0ef41Sopenharmony_ci uint16_t *r=tempTable.resort; 13081cb0ef41Sopenharmony_ci 13091cb0ef41Sopenharmony_ci for(i=0; i<count; ++i) { 13101cb0ef41Sopenharmony_ci oldIndex=tempTable.rows[i].sortIndex; 13111cb0ef41Sopenharmony_ci ds->swapArray16(ds, p+oldIndex, 2, r+i, pErrorCode); 13121cb0ef41Sopenharmony_ci } 13131cb0ef41Sopenharmony_ci uprv_memcpy(q, r, 2*(size_t)count); 13141cb0ef41Sopenharmony_ci 13151cb0ef41Sopenharmony_ci for(i=0; i<count; ++i) { 13161cb0ef41Sopenharmony_ci oldIndex=tempTable.rows[i].sortIndex; 13171cb0ef41Sopenharmony_ci ds->swapArray16(ds, p2+oldIndex, 2, r+i, pErrorCode); 13181cb0ef41Sopenharmony_ci } 13191cb0ef41Sopenharmony_ci uprv_memcpy(q2, r, 2*(size_t)count); 13201cb0ef41Sopenharmony_ci } 13211cb0ef41Sopenharmony_ci } 13221cb0ef41Sopenharmony_ci 13231cb0ef41Sopenharmony_ci if(tempTable.rows!=rows) { 13241cb0ef41Sopenharmony_ci uprv_free(tempTable.rows); 13251cb0ef41Sopenharmony_ci } 13261cb0ef41Sopenharmony_ci 13271cb0ef41Sopenharmony_ci if(U_FAILURE(*pErrorCode)) { 13281cb0ef41Sopenharmony_ci udata_printError(ds, "ucnv_swapAliases().uprv_sortArray(%u items) failed\n", 13291cb0ef41Sopenharmony_ci count); 13301cb0ef41Sopenharmony_ci return 0; 13311cb0ef41Sopenharmony_ci } 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_ci /* swap remaining 16-bit values */ 13341cb0ef41Sopenharmony_ci ds->swapArray16(ds, 13351cb0ef41Sopenharmony_ci inTable+offsets[converterListIndex], 13361cb0ef41Sopenharmony_ci 2*(int32_t)(offsets[aliasListIndex]-offsets[converterListIndex]), 13371cb0ef41Sopenharmony_ci outTable+offsets[converterListIndex], 13381cb0ef41Sopenharmony_ci pErrorCode); 13391cb0ef41Sopenharmony_ci ds->swapArray16(ds, 13401cb0ef41Sopenharmony_ci inTable+offsets[taggedAliasArrayIndex], 13411cb0ef41Sopenharmony_ci 2*(int32_t)(offsets[stringTableIndex]-offsets[taggedAliasArrayIndex]), 13421cb0ef41Sopenharmony_ci outTable+offsets[taggedAliasArrayIndex], 13431cb0ef41Sopenharmony_ci pErrorCode); 13441cb0ef41Sopenharmony_ci } 13451cb0ef41Sopenharmony_ci } 13461cb0ef41Sopenharmony_ci 13471cb0ef41Sopenharmony_ci return headerSize+2*(int32_t)topOffset; 13481cb0ef41Sopenharmony_ci} 13491cb0ef41Sopenharmony_ci 13501cb0ef41Sopenharmony_ci#endif 13511cb0ef41Sopenharmony_ci 13521cb0ef41Sopenharmony_ci 13531cb0ef41Sopenharmony_ci/* 13541cb0ef41Sopenharmony_ci * Hey, Emacs, please set the following: 13551cb0ef41Sopenharmony_ci * 13561cb0ef41Sopenharmony_ci * Local Variables: 13571cb0ef41Sopenharmony_ci * indent-tabs-mode: nil 13581cb0ef41Sopenharmony_ci * End: 13591cb0ef41Sopenharmony_ci * 13601cb0ef41Sopenharmony_ci */ 1361