Home | History | Annotate | Download | only in i18n
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *******************************************************************************
      5 * Copyright (C) 2012-2014, International Business Machines
      6 * Corporation and others.  All Rights Reserved.
      7 *******************************************************************************
      8 * collationroot.cpp
      9 *
     10 * created on: 2012dec17
     11 * created by: Markus W. Scherer
     12 */
     13 
     14 #include "unicode/utypes.h"
     15 
     16 #if !UCONFIG_NO_COLLATION
     17 
     18 #include "unicode/coll.h"
     19 #include "unicode/udata.h"
     20 #include "collation.h"
     21 #include "collationdata.h"
     22 #include "collationdatareader.h"
     23 #include "collationroot.h"
     24 #include "collationsettings.h"
     25 #include "collationtailoring.h"
     26 #include "normalizer2impl.h"
     27 #include "ucln_in.h"
     28 #include "udatamem.h"
     29 #include "umutex.h"
     30 
     31 U_NAMESPACE_BEGIN
     32 
     33 namespace {
     34 
     35 static const CollationCacheEntry *rootSingleton = NULL;
     36 static UInitOnce initOnce = U_INITONCE_INITIALIZER;
     37 
     38 }  // namespace
     39 
     40 U_CDECL_BEGIN
     41 
     42 static UBool U_CALLCONV uprv_collation_root_cleanup() {
     43     SharedObject::clearPtr(rootSingleton);
     44     initOnce.reset();
     45     return TRUE;
     46 }
     47 
     48 U_CDECL_END
     49 
     50 void U_CALLCONV
     51 CollationRoot::load(UErrorCode &errorCode) {
     52     if(U_FAILURE(errorCode)) { return; }
     53     LocalPointer<CollationTailoring> t(new CollationTailoring(NULL));
     54     if(t.isNull() || t->isBogus()) {
     55         errorCode = U_MEMORY_ALLOCATION_ERROR;
     56         return;
     57     }
     58     t->memory = udata_openChoice(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "coll",
     59                                  "icu", "ucadata",
     60                                  CollationDataReader::isAcceptable, t->version, &errorCode);
     61     if(U_FAILURE(errorCode)) { return; }
     62     const uint8_t *inBytes = static_cast<const uint8_t *>(udata_getMemory(t->memory));
     63     CollationDataReader::read(NULL, inBytes, udata_getLength(t->memory), *t, errorCode);
     64     if(U_FAILURE(errorCode)) { return; }
     65     ucln_i18n_registerCleanup(UCLN_I18N_COLLATION_ROOT, uprv_collation_root_cleanup);
     66     CollationCacheEntry *entry = new CollationCacheEntry(Locale::getRoot(), t.getAlias());
     67     if(entry != NULL) {
     68         t.orphan();  // The rootSingleton took ownership of the tailoring.
     69         entry->addRef();
     70         rootSingleton = entry;
     71     }
     72 }
     73 
     74 const CollationCacheEntry *
     75 CollationRoot::getRootCacheEntry(UErrorCode &errorCode) {
     76     umtx_initOnce(initOnce, CollationRoot::load, errorCode);
     77     if(U_FAILURE(errorCode)) { return NULL; }
     78     return rootSingleton;
     79 }
     80 
     81 const CollationTailoring *
     82 CollationRoot::getRoot(UErrorCode &errorCode) {
     83     umtx_initOnce(initOnce, CollationRoot::load, errorCode);
     84     if(U_FAILURE(errorCode)) { return NULL; }
     85     return rootSingleton->tailoring;
     86 }
     87 
     88 const CollationData *
     89 CollationRoot::getData(UErrorCode &errorCode) {
     90     const CollationTailoring *root = getRoot(errorCode);
     91     if(U_FAILURE(errorCode)) { return NULL; }
     92     return root->data;
     93 }
     94 
     95 const CollationSettings *
     96 CollationRoot::getSettings(UErrorCode &errorCode) {
     97     const CollationTailoring *root = getRoot(errorCode);
     98     if(U_FAILURE(errorCode)) { return NULL; }
     99     return root->settings;
    100 }
    101 
    102 U_NAMESPACE_END
    103 
    104 #endif  // !UCONFIG_NO_COLLATION
    105