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 CollationTailoring *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     t->addRef();  // The rootSingleton takes ownership.
     65     rootSingleton = t.orphan();
     66 }
     67 
     68 const CollationTailoring *
     69 CollationRoot::getRoot(UErrorCode &errorCode) {
     70     umtx_initOnce(initOnce, CollationRoot::load, errorCode);
     71     if(U_FAILURE(errorCode)) { return NULL; }
     72     return rootSingleton;
     73 }
     74 
     75 const CollationData *
     76 CollationRoot::getData(UErrorCode &errorCode) {
     77     const CollationTailoring *root = getRoot(errorCode);
     78     if(U_FAILURE(errorCode)) { return NULL; }
     79     return root->data;
     80 }
     81 
     82 const CollationSettings *
     83 CollationRoot::getSettings(UErrorCode &errorCode) {
     84     const CollationTailoring *root = getRoot(errorCode);
     85     if(U_FAILURE(errorCode)) { return NULL; }
     86     return root->settings;
     87 }
     88 
     89 U_NAMESPACE_END
     90 
     91 #endif  // !UCONFIG_NO_COLLATION
     92