1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 459d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1999-2013, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* file name: unames.c 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* encoding: US-ASCII 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* tab size: 8 (not used) 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* indentation:4 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created on: 1999oct04 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created by: Markus W. Scherer 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchar.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h" 2183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf.h" 2283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf16.h" 2359d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_cmn.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "udataswp.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uprops.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3259d709d503bab6e2b61931737e662dd293b40578ccorneliusU_NAMESPACE_BEGIN 3359d709d503bab6e2b61931737e662dd293b40578ccornelius 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* prototypes ------------------------------------------------------------- */ 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char DATA_NAME[] = "unames"; 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char DATA_TYPE[] = "icu"; 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GROUP_SHIFT 5 4283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#define LINES_PER_GROUP (1L<<GROUP_SHIFT) 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GROUP_MASK (LINES_PER_GROUP-1) 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 45b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* 46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * This struct was replaced by explicitly accessing equivalent 47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * fields from triples of uint16_t. 48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * The Group struct was padded to 8 bytes on compilers for early ARM CPUs, 49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * which broke the assumption that sizeof(Group)==6 and that the ++ operator 50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * would advance by 6 bytes (3 uint16_t). 51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * We can't just change the data structure because it's loaded from a data file, 53b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * and we don't want to make it less compact, so we changed the access code. 54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * For details see ICU tickets 6331 and 6008. 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t groupMSB, 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho offsetHigh, offsetLow; / * avoid padding * / 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} Group; 60b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 61b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruenum { 62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GROUP_MSB, 63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GROUP_OFFSET_HIGH, 64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GROUP_OFFSET_LOW, 65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GROUP_LENGTH 66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}; 67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* 69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Get the 32-bit group offset. 70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param group (const uint16_t *) pointer to a Group triple of uint16_t 71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @return group offset (int32_t) 72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define GET_GROUP_OFFSET(group) ((int32_t)(group)[GROUP_OFFSET_HIGH]<<16|(group)[GROUP_OFFSET_LOW]) 74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define NEXT_GROUP(group) ((group)+GROUP_LENGTH) 76b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define PREV_GROUP(group) ((group)-GROUP_LENGTH) 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t start, end; 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t type, variant; 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t size; 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} AlgorithmicRange; 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t tokenStringOffset, groupsOffset, groupStringOffset, algNamesOffset; 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} UCharNames; 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* 89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Get the groups table from a UCharNames struct. 90b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * The groups table consists of one uint16_t groupCount followed by 91b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * groupCount groups. Each group is a triple of uint16_t, see GROUP_LENGTH 92b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * and the comment for the old struct Group above. 93b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 94b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param names (const UCharNames *) pointer to the UCharNames indexes 95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @return (const uint16_t *) pointer to the groups table 96b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define GET_GROUPS(names) (const uint16_t *)((const char *)names+names->groupsOffset) 98b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct { 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *otherName; 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 code; 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} FindName; 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DO_FIND_NAME NULL 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UDataMemory *uCharNamesData=NULL; 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UCharNames *uCharNames=NULL; 10859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gCharNamesInitOnce = U_INITONCE_INITIALIZER; 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Maximum length of character names (regular & 1.0). 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t gMaxNameLength=0; 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set of chars used in character names (regular & 1.0). 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Chars are platform-dependent (can be EBCDIC). 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t gNameSet[8]={ 0 }; 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_NONCHARACTER_CODE_POINT U_CHAR_CATEGORY_COUNT 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_LEAD_SURROGATE U_CHAR_CATEGORY_COUNT + 1 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_TRAIL_SURROGATE U_CHAR_CATEGORY_COUNT + 2 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_CHAR_EXTENDED_CATEGORY_COUNT (U_CHAR_CATEGORY_COUNT + 3) 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const charCatNames[U_CHAR_EXTENDED_CATEGORY_COUNT] = { 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "unassigned", 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "uppercase letter", 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "lowercase letter", 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "titlecase letter", 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "modifier letter", 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "other letter", 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "non spacing mark", 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "enclosing mark", 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "combining spacing mark", 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "decimal digit number", 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "letter number", 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "other number", 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "space separator", 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "line separator", 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "paragraph separator", 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "control", 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "format", 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "private use area", 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "surrogate", 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "dash punctuation", 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "start punctuation", 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "end punctuation", 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "connector punctuation", 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "other punctuation", 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "math symbol", 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "currency symbol", 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "modifier symbol", 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "other symbol", 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "initial punctuation", 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "final punctuation", 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "noncharacter", 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "lead surrogate", 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "trail surrogate" 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* implementation ----------------------------------------------------------- */ 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV unames_cleanup(void) 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uCharNamesData) { 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(uCharNamesData); 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uCharNamesData = NULL; 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uCharNames) { 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uCharNames = NULL; 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 17459d709d503bab6e2b61931737e662dd293b40578ccornelius gCharNamesInitOnce.reset(); 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gMaxNameLength=0; 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV 18083a171d1a62abf406f7f44ae671823d5ec20db7dCraig CorneliusisAcceptable(void * /*context*/, 18183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius const char * /*type*/, const char * /*name*/, 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo) { 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UBool)( 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->size>=20 && 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x75 && /* dataFormat="unam" */ 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x6e && 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x61 && 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x6d && 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]==1); 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 19459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV 19559d709d503bab6e2b61931737e662dd293b40578ccorneliusloadCharNames(UErrorCode &status) { 19659d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(uCharNamesData == NULL); 19759d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(uCharNames == NULL); 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 19959d709d503bab6e2b61931737e662dd293b40578ccornelius uCharNamesData = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &status); 20059d709d503bab6e2b61931737e662dd293b40578ccornelius if(U_FAILURE(status)) { 20159d709d503bab6e2b61931737e662dd293b40578ccornelius uCharNamesData = NULL; 20259d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 20359d709d503bab6e2b61931737e662dd293b40578ccornelius uCharNames = (UCharNames *)udata_getMemory(uCharNamesData); 20459d709d503bab6e2b61931737e662dd293b40578ccornelius } 20559d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_common_registerCleanup(UCLN_COMMON_UNAMES, unames_cleanup); 20659d709d503bab6e2b61931737e662dd293b40578ccornelius} 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UBool 21059d709d503bab6e2b61931737e662dd293b40578ccorneliusisDataLoaded(UErrorCode *pErrorCode) { 21159d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gCharNamesInitOnce, &loadCharNames, *pErrorCode); 21259d709d503bab6e2b61931737e662dd293b40578ccornelius return U_SUCCESS(*pErrorCode); 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) { \ 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((bufferLength)>0) { \ 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *(buffer)++=c; \ 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --(bufferLength); \ 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } \ 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++(bufferPos); \ 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_ISO_COMMENT U_CHAR_NAME_CHOICE_COUNT 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Important: expandName() and compareName() are almost the same - 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * apply fixes to both. 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * UnicodeData.txt uses ';' as a field separator, so no 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * field can contain ';' as part of its contents. 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * In unames.dat, it is marked as token[';']==-1 only if the 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * semicolon is used in the data file - which is iff we 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * have Unicode 1.0 names or ISO comments or aliases. 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * So, it will be token[';']==-1 if we store U1.0 names/ISO comments/aliases 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * although we know that it will never be part of a name. 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint16_t 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruexpandName(UCharNames *names, 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *name, uint16_t nameLength, UCharNameChoice nameChoice, 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *buffer, uint16_t bufferLength) { 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *tokens=(uint16_t *)names+8; 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t token, tokenCount=*tokens++, bufferPos=0; 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *tokenStrings=(uint8_t *)names+names->tokenStringOffset; 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t c; 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(nameChoice!=U_UNICODE_CHAR_NAME && nameChoice!=U_EXTENDED_CHAR_NAME) { 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * skip the modern name if it is not requested _and_ 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if the semicolon byte value is a character, not a token number 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint8_t)';'>=tokenCount || tokens[(uint8_t)';']==(uint16_t)(-1)) { 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int fieldIndex= nameChoice==U_ISO_COMMENT ? 2 : nameChoice; 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho do { 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(nameLength>0) { 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --nameLength; 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*name++==';') { 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } while(--fieldIndex>0); 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the semicolon byte value is a token number, therefore 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * only modern names are stored in unames.dat and there is no 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * such requested alternate name here 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nameLength=0; 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write each letter directly, and write a token word per token */ 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(nameLength>0) { 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --nameLength; 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=*name++; 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>=tokenCount) { 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c!=';') { 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* implicit letter */ 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, bufferPos, c); 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* finished */ 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru token=tokens[c]; 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==(uint16_t)(-2)) { 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this is a lead byte for a double-byte token */ 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru token=tokens[c<<8|*name++]; 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --nameLength; 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==(uint16_t)(-1)) { 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c!=';') { 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* explicit letter */ 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, bufferPos, c); 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* stop, but skip the semicolon if we are seeking 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru extended names and there was no 2.0 name but there 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru is a 1.0 name. */ 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!bufferPos && nameChoice == U_EXTENDED_CHAR_NAME) { 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((uint8_t)';'>=tokenCount || tokens[(uint8_t)';']==(uint16_t)(-1)) { 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* finished */ 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write token word */ 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *tokenString=tokenStrings+token; 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*tokenString++)!=0) { 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, bufferPos, c); 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferLength>0) { 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *buffer=0; 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufferPos; 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * compareName() is almost the same as expandName() except that it compares 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the currently expanded name to an input name. 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * It returns the match/no match result as soon as possible. 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucompareName(UCharNames *names, 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *name, uint16_t nameLength, UCharNameChoice nameChoice, 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *otherName) { 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *tokens=(uint16_t *)names+8; 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t token, tokenCount=*tokens++; 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *tokenStrings=(uint8_t *)names+names->tokenStringOffset; 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t c; 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *origOtherName = otherName; 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(nameChoice!=U_UNICODE_CHAR_NAME && nameChoice!=U_EXTENDED_CHAR_NAME) { 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * skip the modern name if it is not requested _and_ 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if the semicolon byte value is a character, not a token number 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint8_t)';'>=tokenCount || tokens[(uint8_t)';']==(uint16_t)(-1)) { 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int fieldIndex= nameChoice==U_ISO_COMMENT ? 2 : nameChoice; 34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho do { 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(nameLength>0) { 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho --nameLength; 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(*name++==';') { 35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } while(--fieldIndex>0); 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the semicolon byte value is a token number, therefore 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * only modern names are stored in unames.dat and there is no 35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * such requested alternate name here 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nameLength=0; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* compare each letter directly, and compare a token word per token */ 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(nameLength>0) { 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --nameLength; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=*name++; 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>=tokenCount) { 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c!=';') { 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* implicit letter */ 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((char)c!=*otherName++) { 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* finished */ 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru token=tokens[c]; 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==(uint16_t)(-2)) { 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this is a lead byte for a double-byte token */ 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru token=tokens[c<<8|*name++]; 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --nameLength; 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==(uint16_t)(-1)) { 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c!=';') { 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* explicit letter */ 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((char)c!=*otherName++) { 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* stop, but skip the semicolon if we are seeking 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru extended names and there was no 2.0 name but there 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru is a 1.0 name. */ 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(otherName == origOtherName && nameChoice == U_EXTENDED_CHAR_NAME) { 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((uint8_t)';'>=tokenCount || tokens[(uint8_t)';']==(uint16_t)(-1)) { 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* finished */ 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write token word */ 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *tokenString=tokenStrings+token; 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*tokenString++)!=0) { 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((char)c!=*otherName++) { 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* complete match? */ 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UBool)(*otherName==0); 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint8_t getCharCat(UChar32 cp) { 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t cat; 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 42483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if (U_IS_UNICODE_NONCHAR(cp)) { 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return U_NONCHARACTER_CODE_POINT; 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((cat = u_charType(cp)) == U_SURROGATE) { 42983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius cat = U_IS_LEAD(cp) ? U_LEAD_SURROGATE : U_TRAIL_SURROGATE; 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return cat; 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char *getCharCatName(UChar32 cp) { 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t cat = getCharCat(cp); 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Return unknown if the table of names above is not up to 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date. */ 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cat >= LENGTHOF(charCatNames)) { 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return "unknown"; 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return charCatNames[cat]; 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint16_t getExtName(uint32_t code, char *buffer, uint16_t bufferLength) { 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *catname = getCharCatName(code); 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t length = 0; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 cp; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int ndigits, i; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, length, '<'); 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (catname[length - 1]) { 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, length, catname[length - 1]); 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, length, '-'); 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (cp = code, ndigits = 0; cp; ++ndigits, cp >>= 4) 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ; 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ndigits < 4) 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ndigits = 4; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (cp = code, i = ndigits; (cp || i > 0) && bufferLength; cp >>= 4, bufferLength--) { 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t v = (uint8_t)(cp & 0xf); 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[--i] = (v < 10 ? '0' + v : 'A' + v - 10); 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer += ndigits; 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length += ndigits; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, length, '>'); 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length; 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * getGroup() does a binary search for the group that contains the 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Unicode code point "code". 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The return value is always a valid Group* that may contain "code" 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * or else is the highest group before "code". 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If the lowest group is after "code", then that one is returned. 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const uint16_t * 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetGroup(UCharNames *names, uint32_t code) { 484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *groups=GET_GROUPS(names); 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t groupMSB=(uint16_t)(code>>GROUP_SHIFT), 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=0, 487b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru limit=*groups++, 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru number; 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* binary search for the group of names that contains the one for code */ 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<limit-1) { 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru number=(uint16_t)((start+limit)/2); 493b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(groupMSB<groups[number*GROUP_LENGTH+GROUP_MSB]) { 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=number; 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=number; 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* return this regardless of whether it is an exact match */ 501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return groups+start*GROUP_LENGTH; 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * expandGroupLengths() reads a block of compressed lengths of 32 strings and 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * expands them into offsets and lengths for each string. 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Lengths are stored with a variable-width encoding in consecutive nibbles: 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If a nibble<0xc, then it is the length itself (0=empty string). 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If a nibble>=0xc, then it forms a length value with the following nibble. 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Calculation see below. 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The offsets and lengths arrays must be at least 33 (one more) long because 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * there is no check here at the end if the last nibble is still used. 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const uint8_t * 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruexpandGroupLengths(const uint8_t *s, 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t offsets[LINES_PER_GROUP+1], uint16_t lengths[LINES_PER_GROUP+1]) { 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read the lengths of the 32 strings in this group and get each string's offset */ 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t i=0, offset=0, length=0; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t lengthByte; 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* all 32 lengths must be read to get the offset of the first group string */ 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i<LINES_PER_GROUP) { 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthByte=*s++; 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read even nibble - MSBs of lengthByte */ 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>=12) { 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* double-nibble length spread across two bytes */ 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(uint16_t)(((length&0x3)<<4|lengthByte>>4)+12); 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthByte&=0xf; 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if((lengthByte /* &0xf0 */)>=0xc0) { 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* double-nibble length spread across this one byte */ 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(uint16_t)((lengthByte&0x3f)+12); 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* single-nibble length in MSBs */ 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(uint16_t)(lengthByte>>4); 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthByte&=0xf; 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *offsets++=offset; 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *lengths++=length; 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=length; 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read odd nibble - LSBs of lengthByte */ 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((lengthByte&0xf0)==0) { 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this nibble was not consumed for a double-nibble length above */ 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=lengthByte; 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<12) { 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* single-nibble length in LSBs */ 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *offsets++=offset; 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *lengths++=length; 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=length; 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=0; /* prevent double-nibble detection in the next iteration */ 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* now, s is at the first group string */ 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return s; 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint16_t 567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruexpandGroupName(UCharNames *names, const uint16_t *group, 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t lineNumber, UCharNameChoice nameChoice, 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *buffer, uint16_t bufferLength) { 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t offsets[LINES_PER_GROUP+2], lengths[LINES_PER_GROUP+2]; 571b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint8_t *s=(uint8_t *)names+names->groupStringOffset+GET_GROUP_OFFSET(group); 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=expandGroupLengths(s, offsets, lengths); 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return expandName(names, s+offsets[lineNumber], lengths[lineNumber], nameChoice, 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer, bufferLength); 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint16_t 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetName(UCharNames *names, uint32_t code, UCharNameChoice nameChoice, 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *buffer, uint16_t bufferLength) { 580b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *group=getGroup(names, code); 581b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if((uint16_t)(code>>GROUP_SHIFT)==group[GROUP_MSB]) { 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return expandGroupName(names, group, (uint16_t)(code&GROUP_MASK), nameChoice, 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer, bufferLength); 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* group not found */ 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferLength>0) { 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *buffer=0; 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * enumGroupNames() enumerates all the names in a 32-group 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and either calls the enumerator function or finds a given input name. 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 599b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruenumGroupNames(UCharNames *names, const uint16_t *group, 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 start, UChar32 end, 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumCharNamesFn *fn, void *context, 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharNameChoice nameChoice) { 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t offsets[LINES_PER_GROUP+2], lengths[LINES_PER_GROUP+2]; 604b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint8_t *s=(uint8_t *)names+names->groupStringOffset+GET_GROUP_OFFSET(group); 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=expandGroupLengths(s, offsets, lengths); 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fn!=DO_FIND_NAME) { 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buffer[200]; 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t length; 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<=end) { 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=expandName(names, s+offsets[start&GROUP_MASK], lengths[start&GROUP_MASK], nameChoice, buffer, sizeof(buffer)); 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!length && nameChoice == U_EXTENDED_CHAR_NAME) { 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[length = getExtName(start, buffer, sizeof(buffer))] = 0; 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* here, we assume that the buffer is large enough */ 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>0) { 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!fn(context, start, nameChoice, buffer, length)) { 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++start; 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *otherName=((FindName *)context)->otherName; 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<=end) { 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(compareName(names, s+offsets[start&GROUP_MASK], lengths[start&GROUP_MASK], nameChoice, otherName)) { 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((FindName *)context)->code=start; 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++start; 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * enumExtNames enumerate extended names. 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * It only needs to do it if it is called with a real function and not 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with the dummy DO_FIND_NAME, because u_charFromName() does a check 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * for extended names by itself. 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruenumExtNames(UChar32 start, UChar32 end, 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumCharNamesFn *fn, void *context) 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fn!=DO_FIND_NAME) { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buffer[200]; 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t length; 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(start<=end) { 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[length = getExtName(start, buffer, sizeof(buffer))] = 0; 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* here, we assume that the buffer is large enough */ 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>0) { 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!fn(context, start, U_EXTENDED_CHAR_NAME, buffer, length)) { 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++start; 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruenumNames(UCharNames *names, 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 start, UChar32 limit, 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumCharNamesFn *fn, void *context, 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharNameChoice nameChoice) { 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t startGroupMSB, endGroupMSB, groupCount; 672b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *group, *groupLimit; 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startGroupMSB=(uint16_t)(start>>GROUP_SHIFT); 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru endGroupMSB=(uint16_t)((limit-1)>>GROUP_SHIFT); 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* find the group that contains start, or the highest before it */ 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru group=getGroup(names, start); 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 68083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(startGroupMSB<group[GROUP_MSB] && nameChoice==U_EXTENDED_CHAR_NAME) { 68183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius /* enumerate synthetic names between start and the group start */ 68283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius UChar32 extLimit=((UChar32)group[GROUP_MSB]<<GROUP_SHIFT); 68383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(extLimit>limit) { 68483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius extLimit=limit; 68583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 68683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius if(!enumExtNames(start, extLimit-1, fn, context)) { 68783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius return FALSE; 68883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 68983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius start=extLimit; 69083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius } 69183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(startGroupMSB==endGroupMSB) { 693b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(startGroupMSB==group[GROUP_MSB]) { 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if start and limit-1 are in the same group, then enumerate only in that one */ 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return enumGroupNames(names, group, start, limit-1, fn, context, nameChoice); 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 698b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *groups=GET_GROUPS(names); 699b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru groupCount=*groups++; 700b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru groupLimit=groups+groupCount*GROUP_LENGTH; 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 702b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(startGroupMSB==group[GROUP_MSB]) { 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate characters in the partial start group */ 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((start&GROUP_MASK)!=0) { 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!enumGroupNames(names, group, 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start, ((UChar32)startGroupMSB<<GROUP_SHIFT)+LINES_PER_GROUP-1, 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fn, context, nameChoice)) { 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 710b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru group=NEXT_GROUP(group); /* continue with the next group */ 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 712b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(startGroupMSB>group[GROUP_MSB]) { 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make sure that we start enumerating with the first group after start */ 714b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *nextGroup=NEXT_GROUP(group); 715b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (nextGroup < groupLimit && nextGroup[GROUP_MSB] > startGroupMSB && nameChoice == U_EXTENDED_CHAR_NAME) { 716b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 end = nextGroup[GROUP_MSB] << GROUP_SHIFT; 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (end > limit) { 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end = limit; 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!enumExtNames(start, end - 1, fn, context)) { 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 724b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru group=nextGroup; 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate entire groups between the start- and end-groups */ 728b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while(group<groupLimit && group[GROUP_MSB]<endGroupMSB) { 729b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *nextGroup; 730b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru start=(UChar32)group[GROUP_MSB]<<GROUP_SHIFT; 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!enumGroupNames(names, group, start, start+LINES_PER_GROUP-1, fn, context, nameChoice)) { 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 734b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru nextGroup=NEXT_GROUP(group); 735b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (nextGroup < groupLimit && nextGroup[GROUP_MSB] > group[GROUP_MSB] + 1 && nameChoice == U_EXTENDED_CHAR_NAME) { 736b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 end = nextGroup[GROUP_MSB] << GROUP_SHIFT; 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (end > limit) { 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end = limit; 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 740b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (!enumExtNames((group[GROUP_MSB] + 1) << GROUP_SHIFT, end - 1, fn, context)) { 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 744b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru group=nextGroup; 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 747b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* enumerate within the end group (group[GROUP_MSB]==endGroupMSB) */ 748b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(group<groupLimit && group[GROUP_MSB]==endGroupMSB) { 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return enumGroupNames(names, group, (limit-1)&~GROUP_MASK, limit-1, fn, context, nameChoice); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (nameChoice == U_EXTENDED_CHAR_NAME && group == groupLimit) { 751b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 next = (PREV_GROUP(group)[GROUP_MSB] + 1) << GROUP_SHIFT; 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (next > start) { 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = next; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we have not found a group, which means everything is made of 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru extended names. */ 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nameChoice == U_EXTENDED_CHAR_NAME) { 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (limit > UCHAR_MAX_VALUE + 1) { 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit = UCHAR_MAX_VALUE + 1; 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return enumExtNames(start, limit - 1, fn, context); 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint16_t 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruwriteFactorSuffix(const uint16_t *factors, uint16_t count, 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s, /* suffix elements */ 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t code, 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t indexes[8], /* output fields from here */ 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *elementBases[8], const char *elements[8], 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *buffer, uint16_t bufferLength) { 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t i, factor, bufferPos=0; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write elements according to the factors */ 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the factorized elements are determined by modulo arithmetic 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * with the factors of this algorithm 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * note that for fewer operations, count is decremented here 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --count; 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=count; i>0; --i) { 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru factor=factors[i]; 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[i]=(uint16_t)(code%factor); 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru code/=factor; 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we don't need to calculate the last modulus because start<=code<=end 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * guarantees here that code<=factors[0] 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[0]=(uint16_t)code; 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write each element */ 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(elementBases!=NULL) { 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *elementBases++=s; 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip indexes[i] strings */ 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru factor=indexes[i]; 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(factor>0) { 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*s++!=0) {} 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --factor; 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(elements!=NULL) { 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *elements++=s; 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write element */ 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, bufferPos, c); 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we do not need to perform the rest of this loop for i==count - break here */ 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i>=count) { 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip the rest of the strings for this factors[i] */ 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru factor=(uint16_t)(factors[i]-indexes[i]-1); 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(factor>0) { 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*s++!=0) {} 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --factor; 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferLength>0) { 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *buffer=0; 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufferPos; 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Important: 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Parts of findAlgName() are almost the same as some of getAlgName(). 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Fixes must be applied to both. 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint16_t 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetAlgName(AlgorithmicRange *range, uint32_t code, UCharNameChoice nameChoice, 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *buffer, uint16_t bufferLength) { 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t bufferPos=0; 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Only the normative character name can be algorithmic. */ 85750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(nameChoice!=U_UNICODE_CHAR_NAME && nameChoice!=U_EXTENDED_CHAR_NAME) { 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferLength>0) { 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *buffer=0; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(range->type) { 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: { 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix hex-digits */ 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s=(const char *)(range+1); 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t i, count; 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy prefix */ 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, bufferPos, c); 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write hexadecimal code point value */ 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=range->variant; 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count<bufferLength) { 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[count]=0; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=count; i>0;) { 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(--i<bufferLength) { 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=(char)(code&0xf); 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c<10) { 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c+='0'; 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c+='A'-10; 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffer[i]=c; 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru code>>=4; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bufferPos+=count; 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: { 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix factorized-elements */ 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t indexes[8]; 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *factors=(const uint16_t *)(range+1); 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t count=range->variant; 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s=(const char *)(factors+count); 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy prefix */ 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru WRITE_CHAR(buffer, bufferLength, bufferPos, c); 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bufferPos+=writeFactorSuffix(factors, count, 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s, code-range->start, indexes, NULL, NULL, buffer, bufferLength); 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* undefined type */ 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bufferLength>0) { 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *buffer=0; 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bufferPos; 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Important: enumAlgNames() and findAlgName() are almost the same. 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Any fix must be applied to both. 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruenumAlgNames(AlgorithmicRange *range, 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 start, UChar32 limit, 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumCharNamesFn *fn, void *context, 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharNameChoice nameChoice) { 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buffer[200]; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t length; 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 94350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(nameChoice!=U_UNICODE_CHAR_NAME && nameChoice!=U_EXTENDED_CHAR_NAME) { 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(range->type) { 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: { 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *s, *end; 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get the full name of the start character */ 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=getAlgName(range, (uint32_t)start, nameChoice, buffer, sizeof(buffer)); 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<=0) { 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* call the enumerator function with this first character */ 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!fn(context, start, nameChoice, buffer, length)) { 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* go to the end of the name; all these names have the same length */ 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru end=buffer; 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*end!=0) { 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++end; 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate the rest of the names */ 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(++start<limit) { 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* increment the hexadecimal number on a character-basis */ 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=end; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=*--s; 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(('0'<=c && c<'9') || ('A'<=c && c<'F')) { 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *s=(char)(c+1); 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(c=='9') { 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *s='A'; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(c=='F') { 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *s='0'; 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!fn(context, start, nameChoice, buffer, length)) { 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: { 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t indexes[8]; 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *elementBases[8], *elements[8]; 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *factors=(const uint16_t *)(range+1); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t count=range->variant; 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s=(const char *)(factors+count); 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *suffix, *t; 999b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint16_t prefixLength, i, idx; 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix factorized-elements */ 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy prefix */ 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru suffix=buffer; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prefixLength=0; 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *suffix++=c; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++prefixLength; 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* append the suffix of the start character */ 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(uint16_t)(prefixLength+writeFactorSuffix(factors, count, 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s, (uint32_t)start-range->start, 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes, elementBases, elements, 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru suffix, (uint16_t)(sizeof(buffer)-prefixLength))); 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* call the enumerator function with this first character */ 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!fn(context, start, nameChoice, buffer, length)) { 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate the rest of the names */ 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(++start<limit) { 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* increment the indexes in lexical order bound by the factors */ 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=count; 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 1029b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru idx=(uint16_t)(indexes[--i]+1); 1030b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(idx<factors[i]) { 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip one index and its element string */ 1032b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru indexes[i]=idx; 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=elements[i]; 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*s++!=0) { 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru elements[i]=s; 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reset this index to 0 and its element string to the first one */ 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[i]=0; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru elements[i]=elementBases[i]; 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* to make matters a little easier, just append all elements to the suffix */ 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t=suffix; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=prefixLength; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=elements[i]; 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *t++=c; 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++length; 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* zero-terminate */ 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *t=0; 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!fn(context, start, nameChoice, buffer, length)) { 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* undefined type */ 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * findAlgName() is almost the same as enumAlgNames() except that it 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * returns the code point for a name if it fits into the range. 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * It returns 0xffff otherwise. 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UChar32 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufindAlgName(AlgorithmicRange *range, UCharNameChoice nameChoice, const char *otherName) { 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 code; 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 108150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(nameChoice!=U_UNICODE_CHAR_NAME && nameChoice!=U_EXTENDED_CHAR_NAME) { 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0xffff; 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(range->type) { 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: { 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix hex-digits */ 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s=(const char *)(range+1); 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t i, count; 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* compare prefix */ 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((char)c!=*otherName++) { 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0xffff; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read hexadecimal code point value */ 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=range->variant; 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru code=0; 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=*otherName++; 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if('0'<=c && c<='9') { 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru code=(code<<4)|(c-'0'); 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if('A'<=c && c<='F') { 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru code=(code<<4)|(c-'A'+10); 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0xffff; 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* does it fit into the range? */ 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*otherName==0 && range->start<=(uint32_t)code && (uint32_t)code<=range->end) { 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return code; 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: { 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buffer[64]; 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t indexes[8]; 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *elementBases[8], *elements[8]; 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *factors=(const uint16_t *)(range+1); 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t count=range->variant; 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s=(const char *)(factors+count), *t; 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 start, limit; 1128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint16_t i, idx; 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix factorized-elements */ 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* compare prefix */ 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((char)c!=*otherName++) { 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0xffff; 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=(UChar32)range->start; 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit=(UChar32)(range->end+1); 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* initialize the suffix elements for enumeration; indexes should all be set to 0 */ 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writeFactorSuffix(factors, count, s, 0, 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes, elementBases, elements, buffer, sizeof(buffer)); 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* compare the first suffix */ 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(0==uprv_strcmp(otherName, buffer)) { 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return start; 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate and compare the rest of the suffixes */ 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(++start<limit) { 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* increment the indexes in lexical order bound by the factors */ 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=count; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 1158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru idx=(uint16_t)(indexes[--i]+1); 1159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(idx<factors[i]) { 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip one index and its element string */ 1161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru indexes[i]=idx; 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=elements[i]; 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(*s++!=0) {} 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru elements[i]=s; 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reset this index to 0 and its element string to the first one */ 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[i]=0; 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru elements[i]=elementBases[i]; 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* to make matters a little easier, just compare all elements of the suffix */ 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t=otherName; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=elements[i]; 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c!=*t++) { 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=""; /* does not match */ 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=99; 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i<99 && *t==0) { 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return start; 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* undefined type */ 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0xffff; 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* sets of name characters, maximum name lengths ---------------------------- */ 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SET_ADD(set, c) ((set)[(uint8_t)c>>5]|=((uint32_t)1<<((uint8_t)c&0x1f))) 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SET_CONTAINS(set, c) (((set)[(uint8_t)c>>5]&((uint32_t)1<<((uint8_t)c&0x1f)))!=0) 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucalcStringSetLength(uint32_t set[8], const char *s) { 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length=0; 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c; 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while((c=*s++)!=0) { 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SET_ADD(set, c); 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++length; 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length; 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucalcAlgNameSetsLengths(int32_t maxNameLength) { 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru AlgorithmicRange *range; 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t *p; 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t rangeCount; 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length; 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate algorithmic ranges */ 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(uint32_t *)((uint8_t *)uCharNames+uCharNames->algNamesOffset); 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rangeCount=*p; 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru range=(AlgorithmicRange *)(p+1); 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(rangeCount>0) { 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(range->type) { 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix + (range->variant times) hex-digits */ 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* prefix */ 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=calcStringSetLength(gNameSet, (const char *)(range+1))+range->variant; 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>maxNameLength) { 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=length; 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: { 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name = prefix factorized-elements */ 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *factors=(const uint16_t *)(range+1); 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *s; 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, count=range->variant, factor, factorLength, maxFactorLength; 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* prefix length */ 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=(const char *)(factors+count); 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=calcStringSetLength(gNameSet, s); 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s+=length+1; /* start of factor suffixes */ 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get the set and maximum factor suffix length for each factor */ 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxFactorLength=0; 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(factor=factors[i]; factor>0; --factor) { 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru factorLength=calcStringSetLength(gNameSet, s); 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s+=factorLength+1; 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(factorLength>maxFactorLength) { 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxFactorLength=factorLength; 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length+=maxFactorLength; 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>maxNameLength) { 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=length; 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* unknown type */ 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru range=(AlgorithmicRange *)((uint8_t *)range+range->size); 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --rangeCount; 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return maxNameLength; 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucalcExtNameSetsLengths(int32_t maxNameLength) { 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, length; 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<LENGTHOF(charCatNames); ++i) { 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * for each category, count the length of the category name 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * plus 9= 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 2 for <> 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1 for - 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 6 for most hex digits per code point 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=9+calcStringSetLength(gNameSet, charCatNames[i]); 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>maxNameLength) { 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=length; 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return maxNameLength; 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucalcNameSetLength(const uint16_t *tokens, uint16_t tokenCount, const uint8_t *tokenStrings, int8_t *tokenLengths, 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t set[8], 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t **pLine, const uint8_t *lineLimit) { 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *line=*pLine; 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length=0, tokenLength; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t c, token; 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(line!=lineLimit && (c=*line++)!=(uint8_t)';') { 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>=tokenCount) { 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* implicit letter */ 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SET_ADD(set, c); 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++length; 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru token=tokens[c]; 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==(uint16_t)(-2)) { 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this is a lead byte for a double-byte token */ 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=c<<8|*line++; 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru token=tokens[c]; 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==(uint16_t)(-1)) { 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* explicit letter */ 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SET_ADD(set, c); 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++length; 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* count token word */ 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokenLengths!=NULL) { 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* use cached token length */ 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenLength=tokenLengths[c]; 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokenLength==0) { 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenLength=calcStringSetLength(set, (const char *)tokenStrings+token); 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenLengths[c]=(int8_t)tokenLength; 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenLength=calcStringSetLength(set, (const char *)tokenStrings+token); 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length+=tokenLength; 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pLine=line; 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length; 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucalcGroupNameSetsLengths(int32_t maxNameLength) { 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t offsets[LINES_PER_GROUP+2], lengths[LINES_PER_GROUP+2]; 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *tokens=(uint16_t *)uCharNames+8; 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t tokenCount=*tokens++; 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *tokenStrings=(uint8_t *)uCharNames+uCharNames->tokenStringOffset; 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int8_t *tokenLengths; 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1351b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint16_t *group; 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *s, *line, *lineLimit; 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t groupCount, lineNumber, length; 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenLengths=(int8_t *)uprv_malloc(tokenCount); 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokenLengths!=NULL) { 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(tokenLengths, 0, tokenCount); 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru group=GET_GROUPS(uCharNames); 1362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru groupCount=*group++; 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate all groups */ 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(groupCount>0) { 1366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s=(uint8_t *)uCharNames+uCharNames->groupStringOffset+GET_GROUP_OFFSET(group); 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s=expandGroupLengths(s, offsets, lengths); 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate all lines in each group */ 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(lineNumber=0; lineNumber<LINES_PER_GROUP; ++lineNumber) { 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru line=s+offsets[lineNumber]; 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=lengths[lineNumber]; 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length==0) { 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lineLimit=line+length; 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read regular name */ 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=calcNameSetLength(tokens, tokenCount, tokenStrings, tokenLengths, gNameSet, &line, lineLimit); 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>maxNameLength) { 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=length; 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(line==lineLimit) { 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read Unicode 1.0 name */ 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=calcNameSetLength(tokens, tokenCount, tokenStrings, tokenLengths, gNameSet, &line, lineLimit); 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>maxNameLength) { 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=length; 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(line==lineLimit) { 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read ISO comment */ 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*length=calcNameSetLength(tokens, tokenCount, tokenStrings, tokenLengths, gISOCommentSet, &line, lineLimit);*/ 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru group=NEXT_GROUP(group); 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --groupCount; 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokenLengths!=NULL) { 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(tokenLengths); 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set gMax... - name length last for threading */ 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gMaxNameLength=maxNameLength; 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucalcNameSetsLengths(UErrorCode *pErrorCode) { 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const char extChars[]="0123456789ABCDEF<>-"; 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, maxNameLength; 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(gMaxNameLength!=0) { 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!isDataLoaded(pErrorCode)) { 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set hex digits, used in various names, and <>-, used in extended names */ 142783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius for(i=0; i<(int32_t)sizeof(extChars)-1; ++i) { 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SET_ADD(gNameSet, extChars[i]); 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set sets and lengths from algorithmic names */ 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=calcAlgNameSetsLengths(0); 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set sets and lengths from extended names */ 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxNameLength=calcExtNameSetsLengths(maxNameLength); 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set sets and lengths from group names, set global maximum values */ 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru calcGroupNameSetsLengths(maxNameLength); 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1443fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_NAMESPACE_END 1444fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* public API --------------------------------------------------------------- */ 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1447fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_NAMESPACE_USE 1448fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_charName(UChar32 code, UCharNameChoice nameChoice, 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *buffer, int32_t bufferLength, 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1453fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius AlgorithmicRange *algRange; 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t *p; 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length; 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check the argument values */ 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(nameChoice>=U_CHAR_NAME_CHOICE_COUNT || 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bufferLength<0 || (bufferLength>0 && buffer==NULL) 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)code>UCHAR_MAX_VALUE || !isDataLoaded(pErrorCode)) { 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(buffer, bufferLength, 0, pErrorCode); 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=0; 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* try algorithmic names first */ 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(uint32_t *)((uint8_t *)uCharNames+uCharNames->algNamesOffset); 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=*p; 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algRange=(AlgorithmicRange *)(p+1); 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i>0) { 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(algRange->start<=(uint32_t)code && (uint32_t)code<=algRange->end) { 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=getAlgName(algRange, (uint32_t)code, nameChoice, buffer, (uint16_t)bufferLength); 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algRange=(AlgorithmicRange *)((uint8_t *)algRange+algRange->size); 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --i; 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==0) { 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nameChoice == U_EXTENDED_CHAR_NAME) { 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length = getName(uCharNames, (uint32_t )code, U_EXTENDED_CHAR_NAME, buffer, (uint16_t) bufferLength); 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!length) { 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* extended character name */ 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length = getExtName((uint32_t) code, buffer, (uint16_t) bufferLength); 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* normal character name */ 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=getName(uCharNames, (uint32_t)code, nameChoice, buffer, (uint16_t)bufferLength); 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(buffer, bufferLength, length, pErrorCode); 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 150483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Corneliusu_getISOComment(UChar32 /*c*/, 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *dest, int32_t destCapacity, 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check the argument values */ 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(destCapacity<0 || (destCapacity>0 && dest==NULL)) { 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 151583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius return u_terminateChars(dest, destCapacity, 0, pErrorCode); 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UChar32 U_EXPORT2 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_charFromName(UCharNameChoice nameChoice, 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *name, 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char upper[120], lower[120]; 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FindName findName; 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru AlgorithmicRange *algRange; 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t *p; 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 cp = 0; 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char c0; 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 error = 0xffff; /* Undefined, but use this for backwards compatibility. */ 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return error; 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nameChoice>=U_CHAR_NAME_CHOICE_COUNT || name==NULL || *name==0) { 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return error; 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!isDataLoaded(pErrorCode)) { 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return error; 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* construct the uppercase and lowercase of the name first */ 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<sizeof(upper); ++i) { 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((c0=*name++)!=0) { 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru upper[i]=uprv_toupper(c0); 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lower[i]=uprv_tolower(c0); 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru upper[i]=lower[i]=0; 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(i==sizeof(upper)) { 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name too long, there is no such character */ 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_ILLEGAL_CHAR_FOUND; 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return error; 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* try extended names first */ 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lower[0] == '<') { 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nameChoice == U_EXTENDED_CHAR_NAME) { 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lower[--i] == '>') { 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (--i; lower[i] && lower[i] != '-'; --i) { 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lower[i] == '-') { /* We've got a category. */ 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t cIdx; 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lower[i] = 0; 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (++i; lower[i] != '>'; ++i) { 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lower[i] >= '0' && lower[i] <= '9') { 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = (cp << 4) + lower[i] - '0'; 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (lower[i] >= 'a' && lower[i] <= 'f') { 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cp = (cp << 4) + lower[i] - 'a' + 10; 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_ILLEGAL_CHAR_FOUND; 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return error; 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Now validate the category name. 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru We could use a binary search, or a trie, if 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru we really wanted to. */ 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (lower[i] = 0, cIdx = 0; cIdx < LENGTHOF(charCatNames); ++cIdx) { 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!uprv_strcmp(lower + 1, charCatNames[cIdx])) { 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (getCharCat(cp) == cIdx) { 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return cp; 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_ILLEGAL_CHAR_FOUND; 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return error; 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* try algorithmic names now */ 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(uint32_t *)((uint8_t *)uCharNames+uCharNames->algNamesOffset); 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=*p; 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algRange=(AlgorithmicRange *)(p+1); 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i>0) { 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((cp=findAlgName(algRange, nameChoice, upper))!=0xffff) { 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return cp; 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algRange=(AlgorithmicRange *)((uint8_t *)algRange+algRange->size); 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --i; 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* normal character name */ 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru findName.otherName=upper; 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru findName.code=error; 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enumNames(uCharNames, 0, UCHAR_MAX_VALUE + 1, DO_FIND_NAME, &findName, nameChoice); 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (findName.code == error) { 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_ILLEGAL_CHAR_FOUND; 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return findName.code; 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruu_enumCharNames(UChar32 start, UChar32 limit, 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumCharNamesFn *fn, 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru void *context, 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharNameChoice nameChoice, 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru AlgorithmicRange *algRange; 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t *p; 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nameChoice>=U_CHAR_NAME_CHOICE_COUNT || fn==NULL) { 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t) limit > UCHAR_MAX_VALUE + 1) { 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit = UCHAR_MAX_VALUE + 1; 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)start>=(uint32_t)limit) { 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!isDataLoaded(pErrorCode)) { 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* interleave the data-driven ones with the algorithmic ones */ 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* iterate over all algorithmic ranges; assume that they are in ascending order */ 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(uint32_t *)((uint8_t *)uCharNames+uCharNames->algNamesOffset); 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i=*p; 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algRange=(AlgorithmicRange *)(p+1); 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i>0) { 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate the character names before the current algorithmic range */ 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* here: start<limit */ 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)start<algRange->start) { 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)limit<=algRange->start) { 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enumNames(uCharNames, start, limit, fn, context, nameChoice); 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!enumNames(uCharNames, start, (UChar32)algRange->start, fn, context, nameChoice)) { 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=(UChar32)algRange->start; 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate the character names in the current algorithmic range */ 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* here: algRange->start<=start<limit */ 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)start<=algRange->end) { 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)limit<=(algRange->end+1)) { 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enumAlgNames(algRange, start, limit, fn, context, nameChoice); 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!enumAlgNames(algRange, start, (UChar32)algRange->end+1, fn, context, nameChoice)) { 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start=(UChar32)algRange->end+1; 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* continue to the next algorithmic range (here: start<limit) */ 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algRange=(AlgorithmicRange *)((uint8_t *)algRange+algRange->size); 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --i; 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enumerate the character names after the last algorithmic range */ 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enumNames(uCharNames, start, limit, fn, context, nameChoice); 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getMaxCharNameLength() { 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode errorCode=U_ZERO_ERROR; 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(calcNameSetsLengths(&errorCode)) { 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return gMaxNameLength; 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Converts the char set cset into a Unicode set uset. 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param cset Set of 256 bit flags corresponding to a set of chars. 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param uset USet to receive characters. Existing contents are deleted. 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucharSetToUSet(uint32_t cset[8], const USetAdder *sa) { 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar us[256]; 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[256]; 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, length; 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode errorCode; 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!calcNameSetsLengths(&errorCode)) { 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* build a char string with all chars that are used in character names */ 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=0; 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<256; ++i) { 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(SET_CONTAINS(cset, i)) { 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cs[length++]=(char)i; 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* convert the char string to a UChar string */ 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_charsToUChars(cs, us, length); 1733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* add each UChar to the USet */ 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<length; ++i) { 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(us[i]!=0 || cs[i]==0) { /* non-invariant chars become (UChar)0 */ 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sa->add(sa->set, us[i]); 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Fills set with characters that are used in Unicode character names. 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param set USet to receive characters. 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getCharNameCharacters(const USetAdder *sa) { 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru charSetToUSet(gNameSet, sa); 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* data swapping ------------------------------------------------------------ */ 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The token table contains non-negative entries for token bytes, 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and -1 for bytes that represent themselves in the data file's charset. 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * -2 entries are used for lead bytes. 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Direct bytes (-1 entries) must be translated from the input charset family 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to the output charset family. 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * makeTokenMap() writes a permutation mapping for this. 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Use it once for single-/lead-byte tokens and once more for all trail byte 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * tokens. (';' is an unused trail byte marked with -1.) 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerumakeTokenMap(const UDataSwapper *ds, 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t tokens[], uint16_t tokenCount, 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t map[256], 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool usedOutChar[256]; 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t i, j; 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t c1, c2; 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(ds->inCharset==ds->outCharset) { 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Same charset family: identity permutation */ 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<256; ++i) { 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru map[i]=(uint8_t)i; 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(map, 0, 256); 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(usedOutChar, 0, 256); 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokenCount>256) { 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenCount=256; 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set the direct bytes (byte 0 always maps to itself) */ 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=1; i<tokenCount; ++i) { 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokens[i]==-1) { 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* convert the direct byte character */ 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c1=(uint8_t)i; 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapInvChars(ds, &c1, 1, &c2, pErrorCode); 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "unames/makeTokenMap() finds variant character 0x%02x used (input charset family %d)\n", 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i, ds->inCharset); 1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* enter the converted character into the map and mark it used */ 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru map[c1]=c2; 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru usedOutChar[c2]=TRUE; 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set the mappings for the rest of the permutation */ 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=j=1; i<tokenCount; ++i) { 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set mappings that were not set for direct bytes */ 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(map[i]==0) { 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* set an output byte value that was not used as an output byte above */ 1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(usedOutChar[j]) { 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++j; 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru map[i]=(uint8_t)j++; 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * leave mappings at tokenCount and above unset if tokenCount<256 1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * because they won't be used 1823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuchar_swapNames(const UDataSwapper *ds, 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo; 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t headerSize; 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *inBytes; 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *outBytes; 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t tokenStringOffset, groupsOffset, groupStringOffset, algNamesOffset, 1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset, i, count, stringsCount; 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const AlgorithmicRange *inRange; 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru AlgorithmicRange *outRange; 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check data format and format version */ 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!( 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x75 && /* dataFormat="unam" */ 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x6e && 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x61 && 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x6d && 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]==1 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )) { 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "uchar_swapNames(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as unames.icu\n", 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]); 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inBytes=(const uint8_t *)inData+headerSize; 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outBytes=(uint8_t *)outData+headerSize; 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru algNamesOffset=ds->readUInt32(((const uint32_t *)inBytes)[3]); 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length-=headerSize; 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( length<20 || 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (uint32_t)length<(algNamesOffset=ds->readUInt32(((const uint32_t *)inBytes)[3])) 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "uchar_swapNames(): too few bytes (%d after header) for unames.icu\n", 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length); 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* preflighting: iterate through algorithmic ranges */ 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=algNamesOffset; 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=ds->readUInt32(*((const uint32_t *)(inBytes+offset))); 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=4; 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inRange=(const AlgorithmicRange *)(inBytes+offset); 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=ds->readUInt16(inRange->size); 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap data */ 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *p; 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *q, *temp; 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t tokens[512]; 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t tokenCount; 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t map[256], trailMap[256]; 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the data for inaccessible bytes */ 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(inBytes!=outBytes) { 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(outBytes, inBytes, length); 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the initial 4 offsets first */ 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenStringOffset=ds->readUInt32(((const uint32_t *)inBytes)[0]); 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru groupsOffset=ds->readUInt32(((const uint32_t *)inBytes)[1]); 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru groupStringOffset=ds->readUInt32(((const uint32_t *)inBytes)[2]); 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, inBytes, 16, outBytes, pErrorCode); 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * now the tokens table 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * it needs to be permutated along with the compressed name strings 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(const uint16_t *)(inBytes+16); 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q=(uint16_t *)(outBytes+16); 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read and swap the tokenCount */ 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenCount=ds->readUInt16(*p); 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, p, 2, q, pErrorCode); 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++q; 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read the first 512 tokens and make the token maps */ 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokenCount<=512) { 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=tokenCount; 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=512; 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokens[i]=udata_readInt16(ds, p[i]); 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(; i<512; ++i) { 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokens[i]=0; /* fill the rest of the tokens array if tokenCount<512 */ 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru makeTokenMap(ds, tokens, tokenCount, map, pErrorCode); 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru makeTokenMap(ds, tokens+256, (uint16_t)(tokenCount>256 ? tokenCount-256 : 0), trailMap, pErrorCode); 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * swap and permutate the tokens 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * go through a temporary array to support in-place swapping 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru temp=(uint16_t *)uprv_malloc(tokenCount*2); 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(temp==NULL) { 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "out of memory swapping %u unames.icu tokens\n", 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenCount); 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap and permutate single-/lead-byte tokens */ 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<tokenCount && i<256; ++i) { 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, p+i, 2, temp+map[i], pErrorCode); 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap and permutate trail-byte tokens */ 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(; i<tokenCount; ++i) { 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, p+i, 2, temp+(i&0xffffff00)+trailMap[i&0xff], pErrorCode); 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the result into the output and free the temporary array */ 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(q, temp, tokenCount*2); 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(temp); 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * swap the token strings but not a possible padding byte after 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the terminating NUL of the last string 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_swapInvStringBlock(ds, inBytes+tokenStringOffset, (int32_t)(groupsOffset-tokenStringOffset), 1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outBytes+tokenStringOffset, pErrorCode); 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "uchar_swapNames(token strings) failed\n"); 1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the group table */ 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=ds->readUInt16(*((const uint16_t *)(inBytes+groupsOffset))); 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, inBytes+groupsOffset, (int32_t)((1+count*3)*2), 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outBytes+groupsOffset, pErrorCode); 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * swap the group strings 1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * swap the string bytes but not the nibble-encoded string lengths 1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(ds->inCharset!=ds->outCharset) { 1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t offsets[LINES_PER_GROUP+1], lengths[LINES_PER_GROUP+1]; 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *inStrings, *nextInStrings; 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *outStrings; 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t c; 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inStrings=inBytes+groupStringOffset; 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outStrings=outBytes+groupStringOffset; 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stringsCount=algNamesOffset-groupStringOffset; 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* iterate through string groups until only a few padding bytes are left */ 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(stringsCount>32) { 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextInStrings=expandGroupLengths(inStrings, offsets, lengths); 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* move past the length bytes */ 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stringsCount-=(uint32_t)(nextInStrings-inStrings); 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outStrings+=nextInStrings-inStrings; 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inStrings=nextInStrings; 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=offsets[31]+lengths[31]; /* total number of string bytes in this group */ 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stringsCount-=count; 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the string bytes using map[] and trailMap[] */ 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(count>0) { 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c=*inStrings++; 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outStrings++=map[c]; 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tokens[c]!=-2) { 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --count; 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* token lead byte: swap the trail byte, too */ 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *outStrings++=trailMap[*inStrings++]; 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count-=2; 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the algorithmic ranges */ 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=algNamesOffset; 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=ds->readUInt32(*((const uint32_t *)(inBytes+offset))); 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, inBytes+offset, 4, outBytes+offset, pErrorCode); 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=4; 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset>(uint32_t)length) { 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "uchar_swapNames(): too few bytes (%d after header) for unames.icu algorithmic range %u\n", 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length, i); 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inRange=(const AlgorithmicRange *)(inBytes+offset); 2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outRange=(AlgorithmicRange *)(outBytes+offset); 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=ds->readUInt16(inRange->size); 2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, inRange, 8, outRange, pErrorCode); 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, &inRange->size, 2, &outRange->size, pErrorCode); 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(inRange->type) { 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap prefix string */ 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapInvChars(ds, inRange+1, (int32_t)uprv_strlen((const char *)(inRange+1)), 2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outRange+1, pErrorCode); 2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "uchar_swapNames(prefix string of algorithmic range %u) failed\n", 2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i); 2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap factors and the prefix and factor strings */ 2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t factorsCount; 2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru factorsCount=inRange->variant; 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(const uint16_t *)(inRange+1); 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q=(uint16_t *)(outRange+1); 2069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, p, (int32_t)(factorsCount*2), q, pErrorCode); 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the strings, up to the last terminating NUL */ 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p+=factorsCount; 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q+=factorsCount; 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stringsCount=(uint32_t)((inBytes+offset)-(const uint8_t *)p); 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(stringsCount>0 && ((const uint8_t *)p)[stringsCount-1]!=0) { 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --stringsCount; 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapInvChars(ds, p, (int32_t)stringsCount, q, pErrorCode); 2079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 2082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "uchar_swapNames(): unknown type %u of algorithmic range %u\n", 2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inRange->type, i); 2084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 2085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return headerSize+(int32_t)offset; 2091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Hey, Emacs, please set the following: 2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Local Variables: 2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * indent-tabs-mode: nil 2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * End: 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2101