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