11cb0ef41Sopenharmony_ci// © 2016 and later: Unicode, Inc. and others. 21cb0ef41Sopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html 31cb0ef41Sopenharmony_ci/* 41cb0ef41Sopenharmony_ci******************************************************************************* 51cb0ef41Sopenharmony_ci* Copyright (C) 2014, International Business Machines 61cb0ef41Sopenharmony_ci* Corporation and others. All Rights Reserved. 71cb0ef41Sopenharmony_ci******************************************************************************* 81cb0ef41Sopenharmony_ci* loadednormalizer2impl.cpp 91cb0ef41Sopenharmony_ci* 101cb0ef41Sopenharmony_ci* created on: 2014sep03 111cb0ef41Sopenharmony_ci* created by: Markus W. Scherer 121cb0ef41Sopenharmony_ci*/ 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#include "unicode/utypes.h" 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci#if !UCONFIG_NO_NORMALIZATION 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci#include "unicode/udata.h" 191cb0ef41Sopenharmony_ci#include "unicode/localpointer.h" 201cb0ef41Sopenharmony_ci#include "unicode/normalizer2.h" 211cb0ef41Sopenharmony_ci#include "unicode/ucptrie.h" 221cb0ef41Sopenharmony_ci#include "unicode/unistr.h" 231cb0ef41Sopenharmony_ci#include "unicode/unorm.h" 241cb0ef41Sopenharmony_ci#include "cstring.h" 251cb0ef41Sopenharmony_ci#include "mutex.h" 261cb0ef41Sopenharmony_ci#include "norm2allmodes.h" 271cb0ef41Sopenharmony_ci#include "normalizer2impl.h" 281cb0ef41Sopenharmony_ci#include "uassert.h" 291cb0ef41Sopenharmony_ci#include "ucln_cmn.h" 301cb0ef41Sopenharmony_ci#include "uhash.h" 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciU_NAMESPACE_BEGIN 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciclass LoadedNormalizer2Impl : public Normalizer2Impl { 351cb0ef41Sopenharmony_cipublic: 361cb0ef41Sopenharmony_ci LoadedNormalizer2Impl() : memory(nullptr), ownedTrie(nullptr) {} 371cb0ef41Sopenharmony_ci virtual ~LoadedNormalizer2Impl(); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci void load(const char *packageName, const char *name, UErrorCode &errorCode); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ciprivate: 421cb0ef41Sopenharmony_ci static UBool U_CALLCONV 431cb0ef41Sopenharmony_ci isAcceptable(void *context, const char *type, const char *name, const UDataInfo *pInfo); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci UDataMemory *memory; 461cb0ef41Sopenharmony_ci UCPTrie *ownedTrie; 471cb0ef41Sopenharmony_ci}; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ciLoadedNormalizer2Impl::~LoadedNormalizer2Impl() { 501cb0ef41Sopenharmony_ci udata_close(memory); 511cb0ef41Sopenharmony_ci ucptrie_close(ownedTrie); 521cb0ef41Sopenharmony_ci} 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ciUBool U_CALLCONV 551cb0ef41Sopenharmony_ciLoadedNormalizer2Impl::isAcceptable(void * /*context*/, 561cb0ef41Sopenharmony_ci const char * /* type */, const char * /*name*/, 571cb0ef41Sopenharmony_ci const UDataInfo *pInfo) { 581cb0ef41Sopenharmony_ci if( 591cb0ef41Sopenharmony_ci pInfo->size>=20 && 601cb0ef41Sopenharmony_ci pInfo->isBigEndian==U_IS_BIG_ENDIAN && 611cb0ef41Sopenharmony_ci pInfo->charsetFamily==U_CHARSET_FAMILY && 621cb0ef41Sopenharmony_ci pInfo->dataFormat[0]==0x4e && /* dataFormat="Nrm2" */ 631cb0ef41Sopenharmony_ci pInfo->dataFormat[1]==0x72 && 641cb0ef41Sopenharmony_ci pInfo->dataFormat[2]==0x6d && 651cb0ef41Sopenharmony_ci pInfo->dataFormat[3]==0x32 && 661cb0ef41Sopenharmony_ci pInfo->formatVersion[0]==4 671cb0ef41Sopenharmony_ci ) { 681cb0ef41Sopenharmony_ci // Normalizer2Impl *me=(Normalizer2Impl *)context; 691cb0ef41Sopenharmony_ci // uprv_memcpy(me->dataVersion, pInfo->dataVersion, 4); 701cb0ef41Sopenharmony_ci return true; 711cb0ef41Sopenharmony_ci } else { 721cb0ef41Sopenharmony_ci return false; 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci} 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_civoid 771cb0ef41Sopenharmony_ciLoadedNormalizer2Impl::load(const char *packageName, const char *name, UErrorCode &errorCode) { 781cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 791cb0ef41Sopenharmony_ci return; 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci memory=udata_openChoice(packageName, "nrm", name, isAcceptable, this, &errorCode); 821cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 831cb0ef41Sopenharmony_ci return; 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci const uint8_t *inBytes=(const uint8_t *)udata_getMemory(memory); 861cb0ef41Sopenharmony_ci const int32_t *inIndexes=(const int32_t *)inBytes; 871cb0ef41Sopenharmony_ci int32_t indexesLength=inIndexes[IX_NORM_TRIE_OFFSET]/4; 881cb0ef41Sopenharmony_ci if(indexesLength<=IX_MIN_LCCC_CP) { 891cb0ef41Sopenharmony_ci errorCode=U_INVALID_FORMAT_ERROR; // Not enough indexes. 901cb0ef41Sopenharmony_ci return; 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci int32_t offset=inIndexes[IX_NORM_TRIE_OFFSET]; 941cb0ef41Sopenharmony_ci int32_t nextOffset=inIndexes[IX_EXTRA_DATA_OFFSET]; 951cb0ef41Sopenharmony_ci ownedTrie=ucptrie_openFromBinary(UCPTRIE_TYPE_FAST, UCPTRIE_VALUE_BITS_16, 961cb0ef41Sopenharmony_ci inBytes+offset, nextOffset-offset, nullptr, 971cb0ef41Sopenharmony_ci &errorCode); 981cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 991cb0ef41Sopenharmony_ci return; 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci offset=nextOffset; 1031cb0ef41Sopenharmony_ci nextOffset=inIndexes[IX_SMALL_FCD_OFFSET]; 1041cb0ef41Sopenharmony_ci const uint16_t *inExtraData=(const uint16_t *)(inBytes+offset); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci // smallFCD: new in formatVersion 2 1071cb0ef41Sopenharmony_ci offset=nextOffset; 1081cb0ef41Sopenharmony_ci const uint8_t *inSmallFCD=inBytes+offset; 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci init(inIndexes, ownedTrie, inExtraData, inSmallFCD); 1111cb0ef41Sopenharmony_ci} 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci// instance cache ---------------------------------------------------------- *** 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ciNorm2AllModes * 1161cb0ef41Sopenharmony_ciNorm2AllModes::createInstance(const char *packageName, 1171cb0ef41Sopenharmony_ci const char *name, 1181cb0ef41Sopenharmony_ci UErrorCode &errorCode) { 1191cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 1201cb0ef41Sopenharmony_ci return nullptr; 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci LoadedNormalizer2Impl *impl=new LoadedNormalizer2Impl; 1231cb0ef41Sopenharmony_ci if(impl==nullptr) { 1241cb0ef41Sopenharmony_ci errorCode=U_MEMORY_ALLOCATION_ERROR; 1251cb0ef41Sopenharmony_ci return nullptr; 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci impl->load(packageName, name, errorCode); 1281cb0ef41Sopenharmony_ci return createInstance(impl, errorCode); 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciU_CDECL_BEGIN 1321cb0ef41Sopenharmony_cistatic UBool U_CALLCONV uprv_loaded_normalizer2_cleanup(); 1331cb0ef41Sopenharmony_ciU_CDECL_END 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci#if !NORM2_HARDCODE_NFC_DATA 1361cb0ef41Sopenharmony_cistatic Norm2AllModes *nfcSingleton; 1371cb0ef41Sopenharmony_cistatic icu::UInitOnce nfcInitOnce {}; 1381cb0ef41Sopenharmony_ci#endif 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_cistatic Norm2AllModes *nfkcSingleton; 1411cb0ef41Sopenharmony_cistatic icu::UInitOnce nfkcInitOnce {}; 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_cistatic Norm2AllModes *nfkc_cfSingleton; 1441cb0ef41Sopenharmony_cistatic icu::UInitOnce nfkc_cfInitOnce {}; 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_cistatic Norm2AllModes *nfkc_scfSingleton; 1471cb0ef41Sopenharmony_cistatic icu::UInitOnce nfkc_scfInitOnce {}; 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_cistatic UHashtable *cache=nullptr; 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci// UInitOnce singleton initialization function 1521cb0ef41Sopenharmony_cistatic void U_CALLCONV initSingletons(const char *what, UErrorCode &errorCode) { 1531cb0ef41Sopenharmony_ci#if !NORM2_HARDCODE_NFC_DATA 1541cb0ef41Sopenharmony_ci if (uprv_strcmp(what, "nfc") == 0) { 1551cb0ef41Sopenharmony_ci nfcSingleton = Norm2AllModes::createInstance(nullptr, "nfc", errorCode); 1561cb0ef41Sopenharmony_ci } else 1571cb0ef41Sopenharmony_ci#endif 1581cb0ef41Sopenharmony_ci if (uprv_strcmp(what, "nfkc") == 0) { 1591cb0ef41Sopenharmony_ci nfkcSingleton = Norm2AllModes::createInstance(nullptr, "nfkc", errorCode); 1601cb0ef41Sopenharmony_ci } else if (uprv_strcmp(what, "nfkc_cf") == 0) { 1611cb0ef41Sopenharmony_ci nfkc_cfSingleton = Norm2AllModes::createInstance(nullptr, "nfkc_cf", errorCode); 1621cb0ef41Sopenharmony_ci } else if (uprv_strcmp(what, "nfkc_scf") == 0) { 1631cb0ef41Sopenharmony_ci nfkc_scfSingleton = Norm2AllModes::createInstance(nullptr, "nfkc_scf", errorCode); 1641cb0ef41Sopenharmony_ci } else { 1651cb0ef41Sopenharmony_ci UPRV_UNREACHABLE_EXIT; // Unknown singleton 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci ucln_common_registerCleanup(UCLN_COMMON_LOADED_NORMALIZER2, uprv_loaded_normalizer2_cleanup); 1681cb0ef41Sopenharmony_ci} 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ciU_CDECL_BEGIN 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_cistatic void U_CALLCONV deleteNorm2AllModes(void *allModes) { 1731cb0ef41Sopenharmony_ci delete (Norm2AllModes *)allModes; 1741cb0ef41Sopenharmony_ci} 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_cistatic UBool U_CALLCONV uprv_loaded_normalizer2_cleanup() { 1771cb0ef41Sopenharmony_ci#if !NORM2_HARDCODE_NFC_DATA 1781cb0ef41Sopenharmony_ci delete nfcSingleton; 1791cb0ef41Sopenharmony_ci nfcSingleton = nullptr; 1801cb0ef41Sopenharmony_ci nfcInitOnce.reset(); 1811cb0ef41Sopenharmony_ci#endif 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci delete nfkcSingleton; 1841cb0ef41Sopenharmony_ci nfkcSingleton = nullptr; 1851cb0ef41Sopenharmony_ci nfkcInitOnce.reset(); 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci delete nfkc_cfSingleton; 1881cb0ef41Sopenharmony_ci nfkc_cfSingleton = nullptr; 1891cb0ef41Sopenharmony_ci nfkc_cfInitOnce.reset(); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci delete nfkc_scfSingleton; 1921cb0ef41Sopenharmony_ci nfkc_scfSingleton = nullptr; 1931cb0ef41Sopenharmony_ci nfkc_scfInitOnce.reset(); 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci uhash_close(cache); 1961cb0ef41Sopenharmony_ci cache=nullptr; 1971cb0ef41Sopenharmony_ci return true; 1981cb0ef41Sopenharmony_ci} 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ciU_CDECL_END 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci#if !NORM2_HARDCODE_NFC_DATA 2031cb0ef41Sopenharmony_ciconst Norm2AllModes * 2041cb0ef41Sopenharmony_ciNorm2AllModes::getNFCInstance(UErrorCode &errorCode) { 2051cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { return nullptr; } 2061cb0ef41Sopenharmony_ci umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode); 2071cb0ef41Sopenharmony_ci return nfcSingleton; 2081cb0ef41Sopenharmony_ci} 2091cb0ef41Sopenharmony_ci#endif 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ciconst Norm2AllModes * 2121cb0ef41Sopenharmony_ciNorm2AllModes::getNFKCInstance(UErrorCode &errorCode) { 2131cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { return nullptr; } 2141cb0ef41Sopenharmony_ci umtx_initOnce(nfkcInitOnce, &initSingletons, "nfkc", errorCode); 2151cb0ef41Sopenharmony_ci return nfkcSingleton; 2161cb0ef41Sopenharmony_ci} 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ciconst Norm2AllModes * 2191cb0ef41Sopenharmony_ciNorm2AllModes::getNFKC_CFInstance(UErrorCode &errorCode) { 2201cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { return nullptr; } 2211cb0ef41Sopenharmony_ci umtx_initOnce(nfkc_cfInitOnce, &initSingletons, "nfkc_cf", errorCode); 2221cb0ef41Sopenharmony_ci return nfkc_cfSingleton; 2231cb0ef41Sopenharmony_ci} 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ciconst Norm2AllModes * 2261cb0ef41Sopenharmony_ciNorm2AllModes::getNFKC_SCFInstance(UErrorCode &errorCode) { 2271cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { return nullptr; } 2281cb0ef41Sopenharmony_ci umtx_initOnce(nfkc_scfInitOnce, &initSingletons, "nfkc_scf", errorCode); 2291cb0ef41Sopenharmony_ci return nfkc_scfSingleton; 2301cb0ef41Sopenharmony_ci} 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci#if !NORM2_HARDCODE_NFC_DATA 2331cb0ef41Sopenharmony_ciconst Normalizer2 * 2341cb0ef41Sopenharmony_ciNormalizer2::getNFCInstance(UErrorCode &errorCode) { 2351cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode); 2361cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->comp : nullptr; 2371cb0ef41Sopenharmony_ci} 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ciconst Normalizer2 * 2401cb0ef41Sopenharmony_ciNormalizer2::getNFDInstance(UErrorCode &errorCode) { 2411cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode); 2421cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->decomp : nullptr; 2431cb0ef41Sopenharmony_ci} 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ciconst Normalizer2 *Normalizer2Factory::getFCDInstance(UErrorCode &errorCode) { 2461cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode); 2471cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->fcd : nullptr; 2481cb0ef41Sopenharmony_ci} 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ciconst Normalizer2 *Normalizer2Factory::getFCCInstance(UErrorCode &errorCode) { 2511cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode); 2521cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->fcc : nullptr; 2531cb0ef41Sopenharmony_ci} 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ciconst Normalizer2Impl * 2561cb0ef41Sopenharmony_ciNormalizer2Factory::getNFCImpl(UErrorCode &errorCode) { 2571cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode); 2581cb0ef41Sopenharmony_ci return allModes!=nullptr ? allModes->impl : nullptr; 2591cb0ef41Sopenharmony_ci} 2601cb0ef41Sopenharmony_ci#endif 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ciconst Normalizer2 * 2631cb0ef41Sopenharmony_ciNormalizer2::getNFKCInstance(UErrorCode &errorCode) { 2641cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode); 2651cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->comp : nullptr; 2661cb0ef41Sopenharmony_ci} 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ciconst Normalizer2 * 2691cb0ef41Sopenharmony_ciNormalizer2::getNFKDInstance(UErrorCode &errorCode) { 2701cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode); 2711cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->decomp : nullptr; 2721cb0ef41Sopenharmony_ci} 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ciconst Normalizer2 * 2751cb0ef41Sopenharmony_ciNormalizer2::getNFKCCasefoldInstance(UErrorCode &errorCode) { 2761cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFKC_CFInstance(errorCode); 2771cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->comp : nullptr; 2781cb0ef41Sopenharmony_ci} 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ciconst Normalizer2 * 2811cb0ef41Sopenharmony_ciNormalizer2::getNFKCSimpleCasefoldInstance(UErrorCode &errorCode) { 2821cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFKC_SCFInstance(errorCode); 2831cb0ef41Sopenharmony_ci return allModes!=nullptr ? &allModes->comp : nullptr; 2841cb0ef41Sopenharmony_ci} 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ciconst Normalizer2 * 2871cb0ef41Sopenharmony_ciNormalizer2::getInstance(const char *packageName, 2881cb0ef41Sopenharmony_ci const char *name, 2891cb0ef41Sopenharmony_ci UNormalization2Mode mode, 2901cb0ef41Sopenharmony_ci UErrorCode &errorCode) { 2911cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 2921cb0ef41Sopenharmony_ci return nullptr; 2931cb0ef41Sopenharmony_ci } 2941cb0ef41Sopenharmony_ci if(name==nullptr || *name==0) { 2951cb0ef41Sopenharmony_ci errorCode=U_ILLEGAL_ARGUMENT_ERROR; 2961cb0ef41Sopenharmony_ci return nullptr; 2971cb0ef41Sopenharmony_ci } 2981cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=nullptr; 2991cb0ef41Sopenharmony_ci if(packageName==nullptr) { 3001cb0ef41Sopenharmony_ci if(0==uprv_strcmp(name, "nfc")) { 3011cb0ef41Sopenharmony_ci allModes=Norm2AllModes::getNFCInstance(errorCode); 3021cb0ef41Sopenharmony_ci } else if(0==uprv_strcmp(name, "nfkc")) { 3031cb0ef41Sopenharmony_ci allModes=Norm2AllModes::getNFKCInstance(errorCode); 3041cb0ef41Sopenharmony_ci } else if(0==uprv_strcmp(name, "nfkc_cf")) { 3051cb0ef41Sopenharmony_ci allModes=Norm2AllModes::getNFKC_CFInstance(errorCode); 3061cb0ef41Sopenharmony_ci } else if(0==uprv_strcmp(name, "nfkc_scf")) { 3071cb0ef41Sopenharmony_ci allModes=Norm2AllModes::getNFKC_SCFInstance(errorCode); 3081cb0ef41Sopenharmony_ci } 3091cb0ef41Sopenharmony_ci } 3101cb0ef41Sopenharmony_ci if(allModes==nullptr && U_SUCCESS(errorCode)) { 3111cb0ef41Sopenharmony_ci { 3121cb0ef41Sopenharmony_ci Mutex lock; 3131cb0ef41Sopenharmony_ci if(cache!=nullptr) { 3141cb0ef41Sopenharmony_ci allModes=(Norm2AllModes *)uhash_get(cache, name); 3151cb0ef41Sopenharmony_ci } 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci if(allModes==nullptr) { 3181cb0ef41Sopenharmony_ci ucln_common_registerCleanup(UCLN_COMMON_LOADED_NORMALIZER2, uprv_loaded_normalizer2_cleanup); 3191cb0ef41Sopenharmony_ci LocalPointer<Norm2AllModes> localAllModes( 3201cb0ef41Sopenharmony_ci Norm2AllModes::createInstance(packageName, name, errorCode)); 3211cb0ef41Sopenharmony_ci if(U_SUCCESS(errorCode)) { 3221cb0ef41Sopenharmony_ci Mutex lock; 3231cb0ef41Sopenharmony_ci if(cache==nullptr) { 3241cb0ef41Sopenharmony_ci cache=uhash_open(uhash_hashChars, uhash_compareChars, nullptr, &errorCode); 3251cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 3261cb0ef41Sopenharmony_ci return nullptr; 3271cb0ef41Sopenharmony_ci } 3281cb0ef41Sopenharmony_ci uhash_setKeyDeleter(cache, uprv_free); 3291cb0ef41Sopenharmony_ci uhash_setValueDeleter(cache, deleteNorm2AllModes); 3301cb0ef41Sopenharmony_ci } 3311cb0ef41Sopenharmony_ci void *temp=uhash_get(cache, name); 3321cb0ef41Sopenharmony_ci if(temp==nullptr) { 3331cb0ef41Sopenharmony_ci int32_t keyLength= static_cast<int32_t>(uprv_strlen(name)+1); 3341cb0ef41Sopenharmony_ci char *nameCopy=(char *)uprv_malloc(keyLength); 3351cb0ef41Sopenharmony_ci if(nameCopy==nullptr) { 3361cb0ef41Sopenharmony_ci errorCode=U_MEMORY_ALLOCATION_ERROR; 3371cb0ef41Sopenharmony_ci return nullptr; 3381cb0ef41Sopenharmony_ci } 3391cb0ef41Sopenharmony_ci uprv_memcpy(nameCopy, name, keyLength); 3401cb0ef41Sopenharmony_ci allModes=localAllModes.getAlias(); 3411cb0ef41Sopenharmony_ci uhash_put(cache, nameCopy, localAllModes.orphan(), &errorCode); 3421cb0ef41Sopenharmony_ci } else { 3431cb0ef41Sopenharmony_ci // race condition 3441cb0ef41Sopenharmony_ci allModes=(Norm2AllModes *)temp; 3451cb0ef41Sopenharmony_ci } 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci } 3481cb0ef41Sopenharmony_ci } 3491cb0ef41Sopenharmony_ci if(allModes!=nullptr && U_SUCCESS(errorCode)) { 3501cb0ef41Sopenharmony_ci switch(mode) { 3511cb0ef41Sopenharmony_ci case UNORM2_COMPOSE: 3521cb0ef41Sopenharmony_ci return &allModes->comp; 3531cb0ef41Sopenharmony_ci case UNORM2_DECOMPOSE: 3541cb0ef41Sopenharmony_ci return &allModes->decomp; 3551cb0ef41Sopenharmony_ci case UNORM2_FCD: 3561cb0ef41Sopenharmony_ci return &allModes->fcd; 3571cb0ef41Sopenharmony_ci case UNORM2_COMPOSE_CONTIGUOUS: 3581cb0ef41Sopenharmony_ci return &allModes->fcc; 3591cb0ef41Sopenharmony_ci default: 3601cb0ef41Sopenharmony_ci break; // do nothing 3611cb0ef41Sopenharmony_ci } 3621cb0ef41Sopenharmony_ci } 3631cb0ef41Sopenharmony_ci return nullptr; 3641cb0ef41Sopenharmony_ci} 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ciconst Normalizer2 * 3671cb0ef41Sopenharmony_ciNormalizer2Factory::getInstance(UNormalizationMode mode, UErrorCode &errorCode) { 3681cb0ef41Sopenharmony_ci if(U_FAILURE(errorCode)) { 3691cb0ef41Sopenharmony_ci return nullptr; 3701cb0ef41Sopenharmony_ci } 3711cb0ef41Sopenharmony_ci switch(mode) { 3721cb0ef41Sopenharmony_ci case UNORM_NFD: 3731cb0ef41Sopenharmony_ci return Normalizer2::getNFDInstance(errorCode); 3741cb0ef41Sopenharmony_ci case UNORM_NFKD: 3751cb0ef41Sopenharmony_ci return Normalizer2::getNFKDInstance(errorCode); 3761cb0ef41Sopenharmony_ci case UNORM_NFC: 3771cb0ef41Sopenharmony_ci return Normalizer2::getNFCInstance(errorCode); 3781cb0ef41Sopenharmony_ci case UNORM_NFKC: 3791cb0ef41Sopenharmony_ci return Normalizer2::getNFKCInstance(errorCode); 3801cb0ef41Sopenharmony_ci case UNORM_FCD: 3811cb0ef41Sopenharmony_ci return getFCDInstance(errorCode); 3821cb0ef41Sopenharmony_ci default: // UNORM_NONE 3831cb0ef41Sopenharmony_ci return getNoopInstance(errorCode); 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci} 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ciconst Normalizer2Impl * 3881cb0ef41Sopenharmony_ciNormalizer2Factory::getNFKCImpl(UErrorCode &errorCode) { 3891cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode); 3901cb0ef41Sopenharmony_ci return allModes!=nullptr ? allModes->impl : nullptr; 3911cb0ef41Sopenharmony_ci} 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ciconst Normalizer2Impl * 3941cb0ef41Sopenharmony_ciNormalizer2Factory::getNFKC_CFImpl(UErrorCode &errorCode) { 3951cb0ef41Sopenharmony_ci const Norm2AllModes *allModes=Norm2AllModes::getNFKC_CFInstance(errorCode); 3961cb0ef41Sopenharmony_ci return allModes!=nullptr ? allModes->impl : nullptr; 3971cb0ef41Sopenharmony_ci} 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ciU_NAMESPACE_END 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci// C API ------------------------------------------------------------------- *** 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_ciU_NAMESPACE_USE 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ciU_CAPI const UNormalizer2 * U_EXPORT2 4061cb0ef41Sopenharmony_ciunorm2_getNFKCInstance(UErrorCode *pErrorCode) { 4071cb0ef41Sopenharmony_ci return (const UNormalizer2 *)Normalizer2::getNFKCInstance(*pErrorCode); 4081cb0ef41Sopenharmony_ci} 4091cb0ef41Sopenharmony_ci 4101cb0ef41Sopenharmony_ciU_CAPI const UNormalizer2 * U_EXPORT2 4111cb0ef41Sopenharmony_ciunorm2_getNFKDInstance(UErrorCode *pErrorCode) { 4121cb0ef41Sopenharmony_ci return (const UNormalizer2 *)Normalizer2::getNFKDInstance(*pErrorCode); 4131cb0ef41Sopenharmony_ci} 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ciU_CAPI const UNormalizer2 * U_EXPORT2 4161cb0ef41Sopenharmony_ciunorm2_getNFKCCasefoldInstance(UErrorCode *pErrorCode) { 4171cb0ef41Sopenharmony_ci return (const UNormalizer2 *)Normalizer2::getNFKCCasefoldInstance(*pErrorCode); 4181cb0ef41Sopenharmony_ci} 4191cb0ef41Sopenharmony_ci 4201cb0ef41Sopenharmony_ciU_CAPI const UNormalizer2 * U_EXPORT2 4211cb0ef41Sopenharmony_ciunorm2_getNFKCSimpleCasefoldInstance(UErrorCode *pErrorCode) { 4221cb0ef41Sopenharmony_ci return (const UNormalizer2 *)Normalizer2::getNFKCSimpleCasefoldInstance(*pErrorCode); 4231cb0ef41Sopenharmony_ci} 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_ciU_CAPI const UNormalizer2 * U_EXPORT2 4261cb0ef41Sopenharmony_ciunorm2_getInstance(const char *packageName, 4271cb0ef41Sopenharmony_ci const char *name, 4281cb0ef41Sopenharmony_ci UNormalization2Mode mode, 4291cb0ef41Sopenharmony_ci UErrorCode *pErrorCode) { 4301cb0ef41Sopenharmony_ci return (const UNormalizer2 *)Normalizer2::getInstance(packageName, name, mode, *pErrorCode); 4311cb0ef41Sopenharmony_ci} 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ciU_CFUNC UNormalizationCheckResult 4341cb0ef41Sopenharmony_ciunorm_getQuickCheck(UChar32 c, UNormalizationMode mode) { 4351cb0ef41Sopenharmony_ci if(mode<=UNORM_NONE || UNORM_FCD<=mode) { 4361cb0ef41Sopenharmony_ci return UNORM_YES; 4371cb0ef41Sopenharmony_ci } 4381cb0ef41Sopenharmony_ci UErrorCode errorCode=U_ZERO_ERROR; 4391cb0ef41Sopenharmony_ci const Normalizer2 *norm2=Normalizer2Factory::getInstance(mode, errorCode); 4401cb0ef41Sopenharmony_ci if(U_SUCCESS(errorCode)) { 4411cb0ef41Sopenharmony_ci return ((const Normalizer2WithImpl *)norm2)->getQuickCheck(c); 4421cb0ef41Sopenharmony_ci } else { 4431cb0ef41Sopenharmony_ci return UNORM_MAYBE; 4441cb0ef41Sopenharmony_ci } 4451cb0ef41Sopenharmony_ci} 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci#endif // !UCONFIG_NO_NORMALIZATION 448