1f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius/* 2f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius******************************************************************************* 3f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* Copyright (C) 2014, International Business Machines 4f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* Corporation and others. All Rights Reserved. 5f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius******************************************************************************* 6f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* loadednormalizer2impl.cpp 7f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* 8f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* created on: 2014sep03 9f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* created by: Markus W. Scherer 10f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius*/ 11f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 12f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/utypes.h" 13f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 14f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#if !UCONFIG_NO_NORMALIZATION 15f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 16f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/udata.h" 17f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/localpointer.h" 18f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/normalizer2.h" 19f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/unistr.h" 20f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/unorm.h" 21f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "cstring.h" 22f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "mutex.h" 23f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "norm2allmodes.h" 24f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "normalizer2impl.h" 25f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "uassert.h" 26f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "ucln_cmn.h" 27f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "uhash.h" 28f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 29f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_BEGIN 30f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 31f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass LoadedNormalizer2Impl : public Normalizer2Impl { 32f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic: 33f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius LoadedNormalizer2Impl() : memory(NULL), ownedTrie(NULL) {} 34f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius virtual ~LoadedNormalizer2Impl(); 35f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 36f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius void load(const char *packageName, const char *name, UErrorCode &errorCode); 37f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 38f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprivate: 39f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius static UBool U_CALLCONV 40f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius isAcceptable(void *context, const char *type, const char *name, const UDataInfo *pInfo); 41f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 42f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UDataMemory *memory; 43f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UTrie2 *ownedTrie; 44f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}; 45f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 46f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusLoadedNormalizer2Impl::~LoadedNormalizer2Impl() { 47f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius udata_close(memory); 48f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius utrie2_close(ownedTrie); 49f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 50f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 51f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUBool U_CALLCONV 52f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusLoadedNormalizer2Impl::isAcceptable(void * /*context*/, 53f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char * /* type */, const char * /*name*/, 54f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UDataInfo *pInfo) { 55f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if( 56f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->size>=20 && 57f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->isBigEndian==U_IS_BIG_ENDIAN && 58f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->charsetFamily==U_CHARSET_FAMILY && 59f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->dataFormat[0]==0x4e && /* dataFormat="Nrm2" */ 60f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->dataFormat[1]==0x72 && 61f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->dataFormat[2]==0x6d && 62f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->dataFormat[3]==0x32 && 63f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pInfo->formatVersion[0]==2 64f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ) { 65f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Normalizer2Impl *me=(Normalizer2Impl *)context; 66f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // uprv_memcpy(me->dataVersion, pInfo->dataVersion, 4); 67f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 68f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 69f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return FALSE; 70f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 71f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 72f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 73f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid 74f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusLoadedNormalizer2Impl::load(const char *packageName, const char *name, UErrorCode &errorCode) { 75f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 76f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 77f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 78f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius memory=udata_openChoice(packageName, "nrm", name, isAcceptable, this, &errorCode); 79f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 80f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 81f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 82f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const uint8_t *inBytes=(const uint8_t *)udata_getMemory(memory); 83f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const int32_t *inIndexes=(const int32_t *)inBytes; 84f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t indexesLength=inIndexes[IX_NORM_TRIE_OFFSET]/4; 85f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(indexesLength<=IX_MIN_MAYBE_YES) { 86f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius errorCode=U_INVALID_FORMAT_ERROR; // Not enough indexes. 87f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 88f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 89f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 90f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t offset=inIndexes[IX_NORM_TRIE_OFFSET]; 91f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t nextOffset=inIndexes[IX_EXTRA_DATA_OFFSET]; 92f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ownedTrie=utrie2_openFromSerialized(UTRIE2_16_VALUE_BITS, 93f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius inBytes+offset, nextOffset-offset, NULL, 94f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius &errorCode); 95f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 96f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 97f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 98f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 99f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius offset=nextOffset; 100f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nextOffset=inIndexes[IX_SMALL_FCD_OFFSET]; 101f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const uint16_t *inExtraData=(const uint16_t *)(inBytes+offset); 102f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 103f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // smallFCD: new in formatVersion 2 104f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius offset=nextOffset; 105f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const uint8_t *inSmallFCD=inBytes+offset; 106f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 107f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius init(inIndexes, ownedTrie, inExtraData, inSmallFCD); 108f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 109f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 110f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// instance cache ---------------------------------------------------------- *** 111f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 112f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes * 113f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::createInstance(const char *packageName, 114f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char *name, 115f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode &errorCode) { 116f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 117f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 118f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 119f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius LoadedNormalizer2Impl *impl=new LoadedNormalizer2Impl; 120f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(impl==NULL) { 121f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius errorCode=U_MEMORY_ALLOCATION_ERROR; 122f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 123f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 124f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius impl->load(packageName, name, errorCode); 125f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return createInstance(impl, errorCode); 126f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 127f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 128f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_BEGIN 129f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UBool U_CALLCONV uprv_loaded_normalizer2_cleanup(); 130f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_END 131f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 132f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic Norm2AllModes *nfkcSingleton; 133f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic Norm2AllModes *nfkc_cfSingleton; 134f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UHashtable *cache=NULL; 135f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 136f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic icu::UInitOnce nfkcInitOnce = U_INITONCE_INITIALIZER; 137f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic icu::UInitOnce nfkc_cfInitOnce = U_INITONCE_INITIALIZER; 138f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 139f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// UInitOnce singleton initialization function 140f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV initSingletons(const char *what, UErrorCode &errorCode) { 141f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (uprv_strcmp(what, "nfkc") == 0) { 142f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nfkcSingleton = Norm2AllModes::createInstance(NULL, "nfkc", errorCode); 143f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if (uprv_strcmp(what, "nfkc_cf") == 0) { 144f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nfkc_cfSingleton = Norm2AllModes::createInstance(NULL, "nfkc_cf", errorCode); 145f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 146f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(FALSE); // Unknown singleton 147f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 148f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ucln_common_registerCleanup(UCLN_COMMON_LOADED_NORMALIZER2, uprv_loaded_normalizer2_cleanup); 149f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 150f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 151f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_BEGIN 152f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 153f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV deleteNorm2AllModes(void *allModes) { 154f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete (Norm2AllModes *)allModes; 155f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 156f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 157f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UBool U_CALLCONV uprv_loaded_normalizer2_cleanup() { 158f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete nfkcSingleton; 159f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nfkcSingleton = NULL; 160f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete nfkc_cfSingleton; 161f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nfkc_cfSingleton = NULL; 162f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_close(cache); 163f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius cache=NULL; 164f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nfkcInitOnce.reset(); 165f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius nfkc_cfInitOnce.reset(); 166f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 167f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 168f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 169f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_END 170f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 171f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Norm2AllModes * 172f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::getNFKCInstance(UErrorCode &errorCode) { 173f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { return NULL; } 174f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_initOnce(nfkcInitOnce, &initSingletons, "nfkc", errorCode); 175f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return nfkcSingleton; 176f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 177f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 178f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Norm2AllModes * 179f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::getNFKC_CFInstance(UErrorCode &errorCode) { 180f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { return NULL; } 181f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_initOnce(nfkc_cfInitOnce, &initSingletons, "nfkc_cf", errorCode); 182f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return nfkc_cfSingleton; 183f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 184f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 185f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 * 186f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2::getNFKCInstance(UErrorCode &errorCode) { 187f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode); 188f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return allModes!=NULL ? &allModes->comp : NULL; 189f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 190f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 191f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 * 192f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2::getNFKDInstance(UErrorCode &errorCode) { 193f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode); 194f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return allModes!=NULL ? &allModes->decomp : NULL; 195f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 196f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 197f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 * 198f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2::getNFKCCasefoldInstance(UErrorCode &errorCode) { 199f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Norm2AllModes *allModes=Norm2AllModes::getNFKC_CFInstance(errorCode); 200f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return allModes!=NULL ? &allModes->comp : NULL; 201f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 202f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 203f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 * 204f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2::getInstance(const char *packageName, 205f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char *name, 206f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UNormalization2Mode mode, 207f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode &errorCode) { 208f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 209f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 210f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 211f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(name==NULL || *name==0) { 212f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius errorCode=U_ILLEGAL_ARGUMENT_ERROR; 213f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 214f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 215f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Norm2AllModes *allModes=NULL; 216f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(packageName==NULL) { 217f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(0==uprv_strcmp(name, "nfc")) { 218f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius allModes=Norm2AllModes::getNFCInstance(errorCode); 219f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if(0==uprv_strcmp(name, "nfkc")) { 220f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius allModes=Norm2AllModes::getNFKCInstance(errorCode); 221f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if(0==uprv_strcmp(name, "nfkc_cf")) { 222f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius allModes=Norm2AllModes::getNFKC_CFInstance(errorCode); 223f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 224f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 225f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(allModes==NULL && U_SUCCESS(errorCode)) { 226f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius { 227f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius Mutex lock; 228f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(cache!=NULL) { 229f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius allModes=(Norm2AllModes *)uhash_get(cache, name); 230f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 231f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 232f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(allModes==NULL) { 233f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius LocalPointer<Norm2AllModes> localAllModes( 234f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius Norm2AllModes::createInstance(packageName, name, errorCode)); 235f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_SUCCESS(errorCode)) { 236f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius Mutex lock; 237f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(cache==NULL) { 238f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius cache=uhash_open(uhash_hashChars, uhash_compareChars, NULL, &errorCode); 239f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 240f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 241f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 242f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_setKeyDeleter(cache, uprv_free); 243f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_setValueDeleter(cache, deleteNorm2AllModes); 244f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 245f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius void *temp=uhash_get(cache, name); 246f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(temp==NULL) { 247f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t keyLength=uprv_strlen(name)+1; 248f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char *nameCopy=(char *)uprv_malloc(keyLength); 249f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(nameCopy==NULL) { 250f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius errorCode=U_MEMORY_ALLOCATION_ERROR; 251f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 252f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 253f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_memcpy(nameCopy, name, keyLength); 254f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius allModes=localAllModes.getAlias(); 255f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_put(cache, nameCopy, localAllModes.orphan(), &errorCode); 256f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 257f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // race condition 258f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius allModes=(Norm2AllModes *)temp; 259f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 260f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 261f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 262f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 263f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(allModes!=NULL && U_SUCCESS(errorCode)) { 264f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius switch(mode) { 265f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM2_COMPOSE: 266f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return &allModes->comp; 267f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM2_DECOMPOSE: 268f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return &allModes->decomp; 269f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM2_FCD: 270f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return &allModes->fcd; 271f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM2_COMPOSE_CONTIGUOUS: 272f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return &allModes->fcc; 273f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius default: 274f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; // do nothing 275f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 276f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 277f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 278f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 279f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 280f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 * 281f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2Factory::getInstance(UNormalizationMode mode, UErrorCode &errorCode) { 282f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_FAILURE(errorCode)) { 283f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 284f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 285f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius switch(mode) { 286f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM_NFD: 287f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return Normalizer2::getNFDInstance(errorCode); 288f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM_NFKD: 289f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return Normalizer2::getNFKDInstance(errorCode); 290f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM_NFC: 291f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return Normalizer2::getNFCInstance(errorCode); 292f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM_NFKC: 293f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return Normalizer2::getNFKCInstance(errorCode); 294f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UNORM_FCD: 295f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return getFCDInstance(errorCode); 296f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius default: // UNORM_NONE 297f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return getNoopInstance(errorCode); 298f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 299f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 300f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 301f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2Impl * 302f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2Factory::getNFKCImpl(UErrorCode &errorCode) { 303f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode); 304f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return allModes!=NULL ? allModes->impl : NULL; 305f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 306f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 307f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2Impl * 308f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2Factory::getNFKC_CFImpl(UErrorCode &errorCode) { 309f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Norm2AllModes *allModes=Norm2AllModes::getNFKC_CFInstance(errorCode); 310f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return allModes!=NULL ? allModes->impl : NULL; 311f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 312f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 313f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_END 314f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 315f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// C API ------------------------------------------------------------------- *** 316f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 317f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_USE 318f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 319f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const UNormalizer2 * U_EXPORT2 320f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusunorm2_getNFKCInstance(UErrorCode *pErrorCode) { 321f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return (const UNormalizer2 *)Normalizer2::getNFKCInstance(*pErrorCode); 322f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 323f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 324f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const UNormalizer2 * U_EXPORT2 325f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusunorm2_getNFKDInstance(UErrorCode *pErrorCode) { 326f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return (const UNormalizer2 *)Normalizer2::getNFKDInstance(*pErrorCode); 327f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 328f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 329f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const UNormalizer2 * U_EXPORT2 330f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusunorm2_getNFKCCasefoldInstance(UErrorCode *pErrorCode) { 331f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return (const UNormalizer2 *)Normalizer2::getNFKCCasefoldInstance(*pErrorCode); 332f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 333f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 334f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CAPI const UNormalizer2 * U_EXPORT2 335f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusunorm2_getInstance(const char *packageName, 336f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char *name, 337f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UNormalization2Mode mode, 338f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode *pErrorCode) { 339f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return (const UNormalizer2 *)Normalizer2::getInstance(packageName, name, mode, *pErrorCode); 340f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 341f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 342f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CFUNC UNormalizationCheckResult 343f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusunorm_getQuickCheck(UChar32 c, UNormalizationMode mode) { 344f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(mode<=UNORM_NONE || UNORM_FCD<=mode) { 345f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return UNORM_YES; 346f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 347f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode errorCode=U_ZERO_ERROR; 348f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const Normalizer2 *norm2=Normalizer2Factory::getInstance(mode, errorCode); 349f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(U_SUCCESS(errorCode)) { 350f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return ((const Normalizer2WithImpl *)norm2)->getQuickCheck(c); 351f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 352f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return UNORM_MAYBE; 353f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 354f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 355f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 356f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#endif // !UCONFIG_NO_NORMALIZATION 357