1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 459d709d503bab6e2b61931737e662dd293b40578ccornelius * Copyright (C) 2003-2013, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * file name: usprep.cpp 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: 2003jul2 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * created by: Ram Viswanadha 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_IDNA 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/usprep.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unorm.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchar.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uversion.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "sprpimpl.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "udataswp.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_cmn.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ubidi_props.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_USE 3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruStatic cache for already opened StringPrep profiles 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UHashtable *SHARED_DATA_HASHTABLE = NULL; 4559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gSharedDataInitOnce; 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 4754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex usprepMutex = U_MUTEX_INITIALIZER; 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* format version of spp file */ 5054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static uint8_t formatVersion[4]={ 0, 0, 0, 0 }; 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* the Unicode version of the sprep data */ 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UVersionInfo dataVersion={ 0, 0, 0, 0 }; 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* Profile names must be aligned to UStringPrepProfileType */ 5654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic const char * const PROFILE_NAMES[] = { 57b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3491", /* USPREP_RFC3491_NAMEPREP */ 58b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3530cs", /* USPREP_RFC3530_NFS4_CS_PREP */ 59b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3530csci", /* USPREP_RFC3530_NFS4_CS_PREP_CI */ 60b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3491", /* USPREP_RFC3530_NSF4_CIS_PREP */ 61b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3530mixp", /* USPREP_RFC3530_NSF4_MIXED_PREP_PREFIX */ 62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3491", /* USPREP_RFC3530_NSF4_MIXED_PREP_SUFFIX */ 63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3722", /* USPREP_RFC3722_ISCSI */ 64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3920node", /* USPREP_RFC3920_NODEPREP */ 65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc3920res", /* USPREP_RFC3920_RESOURCEPREP */ 66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc4011", /* USPREP_RFC4011_MIB */ 67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc4013", /* USPREP_RFC4013_SASLPREP */ 68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc4505", /* USPREP_RFC4505_TRACE */ 69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc4518", /* USPREP_RFC4518_LDAP */ 70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru "rfc4518ci", /* USPREP_RFC4518_LDAP_CI */ 71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}; 72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruisSPrepAcceptable(void * /* context */, 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * /* type */, 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char * /* name */, 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo) { 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->size>=20 && 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x53 && /* dataFormat="SPRP" */ 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x50 && 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x52 && 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x50 && 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]==3 && 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[2]==UTRIE_SHIFT && 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 9054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius //uprv_memcpy(formatVersion, pInfo->formatVersion, 4); 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(dataVersion, pInfo->dataVersion, 4); 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetSPrepFoldingOffset(uint32_t data) { 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)data; 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* hashes an entry */ 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruhashEntry(const UHashTok parm) { 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepKey *b = (UStringPrepKey *)parm.pointer; 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UHashTok namekey, pathkey; 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru namekey.pointer = b->name; 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pathkey.pointer = b->path; 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uhash_hashChars(namekey)+37*uhash_hashChars(pathkey); 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* compares two entries */ 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucompareEntries(const UHashTok p1, const UHashTok p2) { 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepKey *b1 = (UStringPrepKey *)p1.pointer; 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepKey *b2 = (UStringPrepKey *)p2.pointer; 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UHashTok name1, name2, path1, path2; 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name1.pointer = b1->name; 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name2.pointer = b2->name; 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru path1.pointer = b1->path; 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru path2.pointer = b2->path; 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ((UBool)(uhash_compareChars(name1, name2) & 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uhash_compareChars(path1, path2))); 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_unload(UStringPrepProfile* data){ 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(data->sprepData); 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_internal_flushCache(UBool noRefCount){ 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepProfile *profile = NULL; 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepKey *key = NULL; 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pos = -1; 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t deletedNum = 0; 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UHashElement *e; 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if shared data hasn't even been lazy evaluated yet 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * return 0 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&usprepMutex); 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE == NULL) { 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&usprepMutex); 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*creates an enumeration to iterate through every element in the table */ 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((e = uhash_nextElement(SHARED_DATA_HASHTABLE, &pos)) != NULL) 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru profile = (UStringPrepProfile *) e->value.pointer; 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru key = (UStringPrepKey *) e->key.pointer; 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((noRefCount== FALSE && profile->refCount == 0) || 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru noRefCount== TRUE) { 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru deletedNum++; 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uhash_removeElement(SHARED_DATA_HASHTABLE, e); 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* unload the data */ 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru usprep_unload(profile); 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(key->name != NULL) { 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(key->name); 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru key->name=NULL; 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(key->path != NULL) { 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(key->path); 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru key->path=NULL; 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(profile); 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(key); 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&usprepMutex); 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return deletedNum; 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Works just like ucnv_flushCache() 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_flushCache(){ 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return usprep_internal_flushCache(FALSE); 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV usprep_cleanup(void){ 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE != NULL) { 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru usprep_internal_flushCache(TRUE); 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) { 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uhash_close(SHARED_DATA_HASHTABLE); 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SHARED_DATA_HASHTABLE = NULL; 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 19959d709d503bab6e2b61931737e662dd293b40578ccornelius gSharedDataInitOnce.reset(); 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (SHARED_DATA_HASHTABLE == NULL); 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** Initializes the cache for resources */ 20659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV 20759d709d503bab6e2b61931737e662dd293b40578ccorneliuscreateCache(UErrorCode &status) { 20859d709d503bab6e2b61931737e662dd293b40578ccornelius SHARED_DATA_HASHTABLE = uhash_open(hashEntry, compareEntries, NULL, &status); 20959d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 21059d709d503bab6e2b61931737e662dd293b40578ccornelius SHARED_DATA_HASHTABLE = NULL; 21159d709d503bab6e2b61931737e662dd293b40578ccornelius } 21259d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup); 21359d709d503bab6e2b61931737e662dd293b40578ccornelius} 21459d709d503bab6e2b61931737e662dd293b40578ccornelius 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruinitCache(UErrorCode *status) { 21759d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gSharedDataInitOnce, &createCache, *status); 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruloadData(UStringPrepProfile* profile, 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* path, 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* name, 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* type, 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* errorCode) { 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* load Unicode SPREP data from file */ 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTrie _sprepTrie={ 0,0,0,0,0,0,0 }; 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDataMemory *dataMemory; 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *p=NULL; 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *pb; 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UVersionInfo normUnicodeVersion; 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t normUniVer, sprepUniVer, normCorrVer; 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(errorCode==NULL || U_FAILURE(*errorCode)) { 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* open the data outside the mutex block */ 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //TODO: change the path 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dataMemory=udata_openChoice(path, type, name, isSPrepAcceptable, NULL, errorCode); 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*errorCode)) { 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(const int32_t *)udata_getMemory(dataMemory); 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pb=(const uint8_t *)(p+_SPREP_INDEX_TOP); 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru utrie_unserialize(&_sprepTrie, pb, p[_SPREP_INDEX_TRIE_SIZE], errorCode); 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru _sprepTrie.getFoldingOffset=getSPrepFoldingOffset; 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*errorCode)) { 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(dataMemory); 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* in the mutex block, set the data for this process */ 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&usprepMutex); 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile->sprepData==NULL) { 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru profile->sprepData=dataMemory; 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dataMemory=NULL; 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(&profile->indexes, p, sizeof(profile->indexes)); 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(&profile->sprepTrie, &_sprepTrie, sizeof(UTrie)); 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=(const int32_t *)udata_getMemory(profile->sprepData); 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&usprepMutex); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* initialize some variables */ 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru profile->mappingData=(uint16_t *)((uint8_t *)(p+_SPREP_INDEX_TOP)+profile->indexes[_SPREP_INDEX_TRIE_SIZE]); 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho u_getUnicodeVersion(normUnicodeVersion); 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru normUniVer = (normUnicodeVersion[0] << 24) + (normUnicodeVersion[1] << 16) + 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (normUnicodeVersion[2] << 8 ) + (normUnicodeVersion[3]); 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sprepUniVer = (dataVersion[0] << 24) + (dataVersion[1] << 16) + 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (dataVersion[2] << 8 ) + (dataVersion[3]); 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru normCorrVer = profile->indexes[_SPREP_NORM_CORRECTNS_LAST_UNI_VERSION]; 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*errorCode)){ 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(dataMemory); 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( normUniVer < sprepUniVer && /* the Unicode version of SPREP file must be less than the Unicode Vesion of the normalization data */ 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru normUniVer < normCorrVer && /* the Unicode version of the NormalizationCorrections.txt file should be less than the Unicode Vesion of the normalization data */ 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((profile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0) /* normalization turned on*/ 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ){ 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *errorCode = U_INVALID_FORMAT_ERROR; 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(dataMemory); 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru profile->isDataLoaded = TRUE; 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if a different thread set it first, then close the extra data */ 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dataMemory!=NULL) { 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(dataMemory); /* NULL if it was set correctly */ 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return profile->isDataLoaded; 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UStringPrepProfile* 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_getProfile(const char* path, 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* name, 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status){ 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepProfile* profile = NULL; 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru initCache(status); 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepKey stackKey; 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * const is cast way to save malloc, strcpy and free calls 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we use the passed in pointers for fetching the data from the 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * hash table which is safe 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stackKey.name = (char*) name; 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stackKey.path = (char*) path; 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* fetch the data from the cache */ 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&usprepMutex); 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey)); 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(profile != NULL) { 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho profile->refCount++; 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&usprepMutex); 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(profile == NULL) { 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* else load the data and put the data in the cache */ 33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalMemory<UStringPrepProfile> newProfile; 33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(newProfile.allocateInsteadAndReset() == NULL) { 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* load the data */ 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!loadData(newProfile.getAlias(), path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){ 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 34227f654740f2a26ad62a5c155af9199af9e69b889claireho 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get the options */ 34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0); 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0); 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(newProfile->checkBiDi) { 34827f654740f2a26ad62a5c155af9199af9e69b889claireho newProfile->bdp = ubidi_getSingleton(); 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalMemory<UStringPrepKey> key; 35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalMemory<char> keyName; 35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalMemory<char> keyPath; 35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( key.allocateInsteadAndReset() == NULL || 35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keyName.allocateInsteadAndCopy(uprv_strlen(name)+1) == NULL || 35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (path != NULL && 35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keyPath.allocateInsteadAndCopy(uprv_strlen(path)+1) == NULL) 35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_MEMORY_ALLOCATION_ERROR; 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho usprep_unload(newProfile.getAlias()); 36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&usprepMutex); 36527f654740f2a26ad62a5c155af9199af9e69b889claireho // If another thread already inserted the same key/value, refcount and cleanup our thread data 36627f654740f2a26ad62a5c155af9199af9e69b889claireho profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey)); 36727f654740f2a26ad62a5c155af9199af9e69b889claireho if(profile != NULL) { 36827f654740f2a26ad62a5c155af9199af9e69b889claireho profile->refCount++; 36927f654740f2a26ad62a5c155af9199af9e69b889claireho usprep_unload(newProfile.getAlias()); 37027f654740f2a26ad62a5c155af9199af9e69b889claireho } 37127f654740f2a26ad62a5c155af9199af9e69b889claireho else { 37227f654740f2a26ad62a5c155af9199af9e69b889claireho /* initialize the key members */ 37327f654740f2a26ad62a5c155af9199af9e69b889claireho key->name = keyName.orphan(); 37427f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(key->name, name); 37527f654740f2a26ad62a5c155af9199af9e69b889claireho if(path != NULL){ 37627f654740f2a26ad62a5c155af9199af9e69b889claireho key->path = keyPath.orphan(); 37727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(key->path, path); 37827f654740f2a26ad62a5c155af9199af9e69b889claireho } 37927f654740f2a26ad62a5c155af9199af9e69b889claireho profile = newProfile.orphan(); 38027f654740f2a26ad62a5c155af9199af9e69b889claireho 38127f654740f2a26ad62a5c155af9199af9e69b889claireho /* add the data object to the cache */ 38227f654740f2a26ad62a5c155af9199af9e69b889claireho profile->refCount = 1; 38327f654740f2a26ad62a5c155af9199af9e69b889claireho uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status); 38427f654740f2a26ad62a5c155af9199af9e69b889claireho } 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&usprepMutex); 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return profile; 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UStringPrepProfile* U_EXPORT2 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_open(const char* path, 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* name, 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status){ 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)){ 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* initialize the profile struct members */ 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return usprep_getProfile(path,name,status); 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI UStringPrepProfile* U_EXPORT2 405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruusprep_openByType(UStringPrepProfileType type, 406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode* status) { 407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(status == NULL || U_FAILURE(*status)){ 408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t index = (int32_t)type; 411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (index < 0 || index >= (int32_t)(sizeof(PROFILE_NAMES)/sizeof(PROFILE_NAMES[0]))) { 412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return usprep_open(NULL, PROFILE_NAMES[index], status); 416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_close(UStringPrepProfile* profile){ 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile==NULL){ 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&usprepMutex); 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* decrement the ref count*/ 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile->refCount > 0){ 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru profile->refCount--; 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&usprepMutex); 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_syntaxError(const UChar* rules, 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pos, 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rulesLen, 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError* parseError){ 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(parseError == NULL){ 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseError->offset = pos; 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseError->line = 0 ; // we are not using line numbers 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for pre-context 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start = (pos < U_PARSE_CONTEXT_LEN)? 0 : (pos - (U_PARSE_CONTEXT_LEN-1)); 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit = pos; 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_memcpy(parseError->preContext,rules+start,limit-start); 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //null terminate the buffer 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseError->preContext[limit-start] = 0; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for post-context; include error rules[pos] 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = pos; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit = start + (U_PARSE_CONTEXT_LEN-1); 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (limit > rulesLen) { 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru limit = rulesLen; 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (start < rulesLen) { 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_memcpy(parseError->postContext,rules+start,limit-start); 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //null terminate the buffer 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseError->postContext[limit-start]= 0; 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic inline UStringPrepType 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetValues(uint16_t trieWord, int16_t& value, UBool& isIndex){ 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepType type; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(trieWord == 0){ 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Initial value stored in the mapping table 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * just return USPREP_TYPE_LIMIT .. so that 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the source codepoint is copied to the destination 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = USPREP_TYPE_LIMIT; 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isIndex =FALSE; 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = 0; 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else if(trieWord >= _SPREP_TYPE_THRESHOLD){ 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = (UStringPrepType) (trieWord - _SPREP_TYPE_THRESHOLD); 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isIndex =FALSE; 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = 0; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get the type */ 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = USPREP_MAP; 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ascertain if the value is index or delta */ 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(trieWord & 0x02){ 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isIndex = TRUE; 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = trieWord >> 2; //mask off the lower 2 bits and shift 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isIndex = FALSE; 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = (int16_t)trieWord; 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = (value >> 2); 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((trieWord>>2) == _SPREP_MAX_INDEX_VALUE){ 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = USPREP_DELETE; 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isIndex =FALSE; 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = 0; 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return type; 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_map( const UStringPrepProfile* profile, 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* src, int32_t srcLength, 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* dest, int32_t destCapacity, 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t options, 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError* parseError, 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status ){ 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t result; 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t destIndex=0; 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcIndex; 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool allowUnassigned = (UBool) ((options & USPREP_ALLOW_UNASSIGNED)>0); 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepType type; 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t value; 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isIndex; 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t* indexes = profile->indexes; 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no error checking the caller check for error and arguments 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no string length check the caller finds out the string length 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(srcIndex=0;srcIndex<srcLength;){ 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 ch; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U16_NEXT(src,srcIndex,srcLength,ch); 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result=0; 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRIE_GET16(&profile->sprepTrie,ch,result); 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = getValues(result, value, isIndex); 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // check if the source codepoint is unassigned 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(type == USPREP_UNASSIGNED && allowUnassigned == FALSE){ 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_syntaxError(src,srcIndex-U16_LENGTH(ch), srcLength,parseError); 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_STRINGPREP_UNASSIGNED_ERROR; 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else if(type == USPREP_MAP){ 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t index, length; 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isIndex){ 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index = value; 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(index >= indexes[_SPREP_ONE_UCHAR_MAPPING_INDEX_START] && 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index < indexes[_SPREP_TWO_UCHARS_MAPPING_INDEX_START]){ 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length = 1; 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else if(index >= indexes[_SPREP_TWO_UCHARS_MAPPING_INDEX_START] && 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index < indexes[_SPREP_THREE_UCHARS_MAPPING_INDEX_START]){ 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length = 2; 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else if(index >= indexes[_SPREP_THREE_UCHARS_MAPPING_INDEX_START] && 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index < indexes[_SPREP_FOUR_UCHARS_MAPPING_INDEX_START]){ 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length = 3; 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length = profile->mappingData[index++]; 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy mapping to destination */ 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int32_t i=0; i< length; i++){ 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(destIndex < destCapacity ){ 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dest[destIndex] = profile->mappingData[index+i]; 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru destIndex++; /* for pre-flighting */ 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // subtract the delta to arrive at the code point 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ch -= value; 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else if(type==USPREP_DELETE){ 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // just consume the codepoint and contine 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //copy the code point into destination 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(ch <= 0xFFFF){ 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(destIndex < destCapacity ){ 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dest[destIndex] = (UChar)ch; 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru destIndex++; 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(destIndex+1 < destCapacity ){ 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dest[destIndex] = U16_LEAD(ch); 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dest[destIndex+1] = U16_TRAIL(ch); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru destIndex +=2; 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateUChars(dest, destCapacity, destIndex, status); 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_normalize( const UChar* src, int32_t srcLength, 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* dest, int32_t destCapacity, 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status ){ 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return unorm_normalize( 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru src, srcLength, 60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UNORM_NFKC, UNORM_UNICODE_3_2, 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dest, destCapacity, 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status); 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1) Map -- For each character in the input, check if it has a mapping 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru and, if so, replace it with its mapping. 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2) Normalize -- Possibly normalize the result of step 1 using Unicode 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru normalization. 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3) Prohibit -- Check for any characters that are not allowed in the 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru output. If any are found, return an error. 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 4) Check bidi -- Possibly check for right-to-left characters, and if 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru any are found, make sure that the whole string satisfies the 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru requirements for bidirectional strings. If the string does not 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru satisfy the requirements for bidirectional strings, return an 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error. 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru [Unicode3.2] defines several bidirectional categories; each character 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru has one bidirectional category assigned to it. For the purposes of 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru the requirements below, an "RandALCat character" is a character that 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru has Unicode bidirectional categories "R" or "AL"; an "LCat character" 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru is a character that has Unicode bidirectional category "L". Note 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru that there are many characters which fall in neither of the above 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru definitions; Latin digits (<U+0030> through <U+0039>) are examples of 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru this because they have bidirectional category "EN". 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru In any profile that specifies bidirectional character handling, all 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru three of the following requirements MUST be met: 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1) The characters in section 5.8 MUST be prohibited. 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2) If a string contains any RandALCat character, the string MUST NOT 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru contain any LCat character. 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3) If a string contains any RandALCat character, a RandALCat 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru character MUST be the first character of the string, and a 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RandALCat character MUST be the last character of the string. 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MAX_STACK_BUFFER_SIZE 300 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_prepare( const UStringPrepProfile* profile, 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* src, int32_t srcLength, 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* dest, int32_t destCapacity, 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t options, 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError* parseError, 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* status ){ 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // check error status 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)){ 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //check arguments 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile==NULL || src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) { 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_ILLEGAL_ARGUMENT_ERROR; 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar b1Stack[MAX_STACK_BUFFER_SIZE], b2Stack[MAX_STACK_BUFFER_SIZE]; 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *b1 = b1Stack, *b2 = b2Stack; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t b1Len, b2Len=0, 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b1Capacity = MAX_STACK_BUFFER_SIZE , 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2Capacity = MAX_STACK_BUFFER_SIZE; 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t result; 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t b2Index = 0; 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCharDirection direction=U_CHAR_DIRECTION_COUNT, firstCharDir=U_CHAR_DIRECTION_COUNT; 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool leftToRight=FALSE, rightToLeft=FALSE; 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rtlPos =-1, ltrPos =-1; 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //get the string length 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength == -1){ 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(src); 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // map 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b1Len = usprep_map(profile, src, srcLength, b1, b1Capacity, options, parseError, status); 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*status == U_BUFFER_OVERFLOW_ERROR){ 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // redo processing of string 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we do not have enough room so grow the buffer*/ 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(b1==NULL){ 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto CLEANUP; 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; // reset error 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b1Len = usprep_map(profile, src, srcLength, b1, b1Len, options, parseError, status); 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // normalize 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile->doNFKC == TRUE){ 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2Len = usprep_normalize(b1,b1Len, b2,b2Capacity,status); 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*status == U_BUFFER_OVERFLOW_ERROR){ 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // redo processing of string 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we do not have enough room so grow the buffer*/ 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(b2==NULL){ 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto CLEANUP; 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; // reset error 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2Len = usprep_normalize(b1,b1Len, b2,b2Len,status); 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2 = b1; 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2Len = b1Len; 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto CLEANUP; 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 ch; 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UStringPrepType type; 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int16_t value; 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isIndex; 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Prohibit and checkBiDi in one pass 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(b2Index=0; b2Index<b2Len;){ 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ch = 0; 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U16_NEXT(b2, b2Index, b2Len, ch); 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRIE_GET16(&profile->sprepTrie,ch,result); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = getValues(result, value, isIndex); 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( type == USPREP_PROHIBITED || 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((result < _SPREP_TYPE_THRESHOLD) && (result & 0x01) /* first bit says it the code point is prohibited*/) 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ){ 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_STRINGPREP_PROHIBITED_ERROR; 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_syntaxError(b1, b2Index-U16_LENGTH(ch), b2Len, parseError); 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto CLEANUP; 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile->checkBiDi) { 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru direction = ubidi_getClass(profile->bdp, ch); 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(firstCharDir == U_CHAR_DIRECTION_COUNT){ 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstCharDir = direction; 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(direction == U_LEFT_TO_RIGHT){ 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leftToRight = TRUE; 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ltrPos = b2Index-1; 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC){ 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rightToLeft = TRUE; 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rtlPos = b2Index-1; 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(profile->checkBiDi == TRUE){ 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // satisfy 2 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( leftToRight == TRUE && rightToLeft == TRUE){ 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_STRINGPREP_CHECK_BIDI_ERROR; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_syntaxError(b2,(rtlPos>ltrPos) ? rtlPos : ltrPos, b2Len, parseError); 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto CLEANUP; 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //satisfy 3 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( rightToLeft == TRUE && 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru !((firstCharDir == U_RIGHT_TO_LEFT || firstCharDir == U_RIGHT_TO_LEFT_ARABIC) && 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC)) 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ){ 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_STRINGPREP_CHECK_BIDI_ERROR; 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_syntaxError(b2, rtlPos, b2Len, parseError); 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(b2Len>0 && b2Len <= destCapacity){ 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(dest,b2, b2Len*U_SIZEOF_UCHAR); 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCLEANUP: 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(b1!=b1Stack){ 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(b1); 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b1=NULL; 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(b2!=b1Stack && b2!=b2Stack && b2!=b1 /* b1 should not be freed twice */){ 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(b2); 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru b2=NULL; 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateUChars(dest, destCapacity, b2Len, status); 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* data swapping ------------------------------------------------------------ */ 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusprep_swap(const UDataSwapper *ds, 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo; 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t headerSize; 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *inBytes; 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *outBytes; 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *inIndexes; 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t indexes[16]; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, offset, count, size; 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check data format and format version */ 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!( 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x53 && /* dataFormat="SPRP" */ 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x50 && 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x52 && 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x50 && 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]==3 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )) { 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "usprep_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as StringPrep .spp data\n", 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]); 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inBytes=(const uint8_t *)inData+headerSize; 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outBytes=(uint8_t *)outData+headerSize; 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inIndexes=(const int32_t *)inBytes; 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>=0) { 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length-=headerSize; 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<16*4) { 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "usprep_swap(): too few bytes (%d after header) for StringPrep .spp data\n", 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length); 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read the first 16 indexes (ICU 2.8/format version 3: _SPREP_INDEX_TOP==16, might grow) */ 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<16; ++i) { 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[i]=udata_readInt32(ds, inIndexes[i]); 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* calculate the total length of the data */ 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size= 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16*4+ /* size of indexes[] */ 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[_SPREP_INDEX_TRIE_SIZE]+ 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[_SPREP_INDEX_MAPPING_DATA_SIZE]; 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>=0) { 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<size) { 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "usprep_swap(): too few bytes (%d after header) for all of StringPrep .spp data\n", 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length); 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the data for inaccessible bytes */ 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(inBytes!=outBytes) { 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(outBytes, inBytes, size); 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=0; 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the int32_t indexes[] */ 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=16*4; 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, inBytes, count, outBytes, pErrorCode); 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=count; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the UTrie */ 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=indexes[_SPREP_INDEX_TRIE_SIZE]; 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru utrie_swap(ds, inBytes+offset, count, outBytes+offset, pErrorCode); 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=count; 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the uint16_t mappingTable[] */ 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=indexes[_SPREP_INDEX_MAPPING_DATA_SIZE]; 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, inBytes+offset, count, outBytes+offset, pErrorCode); 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=count; 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return headerSize+size; 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_IDNA */ 913