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