intl/icu/source/common/servls.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /**
     2  *******************************************************************************
     3  * Copyright (C) 2001-2012, International Business Machines Corporation and    *
     4  * others. All Rights Reserved.                                                *
     5  *******************************************************************************
     6  *
     7  *******************************************************************************
     8  */
     9 #include "unicode/utypes.h"
    11 #if !UCONFIG_NO_SERVICE
    13 #include "unicode/resbund.h"
    14 #include "uresimp.h"
    15 #include "cmemory.h"
    16 #include "servloc.h"
    17 #include "ustrfmt.h"
    18 #include "charstr.h"
    19 #include "ucln_cmn.h"
    20 #include "uassert.h"
    22 #define UNDERSCORE_CHAR ((UChar)0x005f)
    23 #define AT_SIGN_CHAR    ((UChar)64)
    24 #define PERIOD_CHAR     ((UChar)46)
    26 U_NAMESPACE_BEGIN
    28 static UMutex llock = U_MUTEX_INITIALIZER;
    29 ICULocaleService::ICULocaleService()
    30   : fallbackLocale(Locale::getDefault())
    31 {
    32 }
    34 ICULocaleService::ICULocaleService(const UnicodeString& dname)
    35   : ICUService(dname)
    36   , fallbackLocale(Locale::getDefault())
    37 {
    38 }
    40 ICULocaleService::~ICULocaleService()
    41 {
    42 }
    44 UObject*
    45 ICULocaleService::get(const Locale& locale, UErrorCode& status) const
    46 {
    47     return get(locale, LocaleKey::KIND_ANY, NULL, status);
    48 }
    50 UObject*
    51 ICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const
    52 {
    53     return get(locale, kind, NULL, status);
    54 }
    56 UObject*
    57 ICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const
    58 {
    59     return get(locale, LocaleKey::KIND_ANY, actualReturn, status);
    60 }
    62 UObject*
    63 ICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const
    64 {
    65     UObject* result = NULL;
    66     if (U_FAILURE(status)) {
    67         return result;
    68     }
    70     UnicodeString locName(locale.getName(), -1, US_INV);
    71     if (locName.isBogus()) {
    72         status = U_MEMORY_ALLOCATION_ERROR;
    73     } else {
    74         ICUServiceKey* key = createKey(&locName, kind, status);
    75         if (key) {
    76             if (actualReturn == NULL) {
    77                 result = getKey(*key, status);
    78             } else {
    79                 UnicodeString temp;
    80                 result = getKey(*key, &temp, status);
    82                 if (result != NULL) {
    83                     key->parseSuffix(temp);
    84                     LocaleUtility::initLocaleFromName(temp, *actualReturn);
    85                 }
    86             }
    87             delete key;
    88         }
    89     }
    90     return result;
    91 }
    94 URegistryKey
    95 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, 
    96     UBool visible, UErrorCode& status)
    97 {
    98     Locale loc;
    99     LocaleUtility::initLocaleFromName(locale, loc);
   100     return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY, 
   101         visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status);
   102 }
   104 URegistryKey
   105 ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status)
   106 {
   107     return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
   108 }
   110 URegistryKey
   111 ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status)
   112 {
   113     return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status);
   114 }
   116 URegistryKey
   117 ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status)
   118 {
   119     ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
   120     if (factory != NULL) {
   121         return registerFactory(factory, status);
   122     }
   123     delete objToAdopt;
   124     return NULL;
   125 }
   127 #if 0
   128 URegistryKey
   129 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status)
   130 {
   131     return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
   132 }
   134 URegistryKey
   135 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status)
   136 {
   137     return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY,
   138                             visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE,
   139                             status);
   140 }
   142 URegistryKey
   143 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status)
   144 {
   145     ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
   146     if (factory != NULL) {
   147         return registerFactory(factory, status);
   148     }
   149     delete objToAdopt;
   150     return NULL;
   151 }
   152 #endif
   154 class ServiceEnumeration : public StringEnumeration {
   155 private:
   156     const ICULocaleService* _service;
   157     int32_t _timestamp;
   158     UVector _ids;
   159     int32_t _pos;
   161 private:
   162     ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
   163         : _service(service)
   164         , _timestamp(service->getTimestamp())
   165         , _ids(uprv_deleteUObject, NULL, status)
   166         , _pos(0)
   167     {
   168         _service->getVisibleIDs(_ids, status);
   169     }
   171     ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status)
   172         : _service(other._service)
   173         , _timestamp(other._timestamp)
   174         , _ids(uprv_deleteUObject, NULL, status)
   175         , _pos(0)
   176     {
   177         if(U_SUCCESS(status)) {
   178             int32_t i, length;
   180             length = other._ids.size();
   181             for(i = 0; i < length; ++i) {
   182                 _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
   183             }
   185             if(U_SUCCESS(status)) {
   186                 _pos = other._pos;
   187             }
   188         }
   189     }
   191 public:
   192     static ServiceEnumeration* create(const ICULocaleService* service) {
   193         UErrorCode status = U_ZERO_ERROR;
   194         ServiceEnumeration* result = new ServiceEnumeration(service, status);
   195         if (U_SUCCESS(status)) {
   196             return result;
   197         }
   198         delete result;
   199         return NULL;
   200     }
   202     virtual ~ServiceEnumeration();
   204     virtual StringEnumeration *clone() const {
   205         UErrorCode status = U_ZERO_ERROR;
   206         ServiceEnumeration *cl = new ServiceEnumeration(*this, status);
   207         if(U_FAILURE(status)) {
   208             delete cl;
   209             cl = NULL;
   210         }
   211         return cl;
   212     }
   214     UBool upToDate(UErrorCode& status) const {
   215         if (U_SUCCESS(status)) {
   216             if (_timestamp == _service->getTimestamp()) {
   217                 return TRUE;
   218             }
   219             status = U_ENUM_OUT_OF_SYNC_ERROR;
   220         }
   221         return FALSE;
   222     }
   224     virtual int32_t count(UErrorCode& status) const {
   225         return upToDate(status) ? _ids.size() : 0;
   226     }
   228     virtual const UnicodeString* snext(UErrorCode& status) {
   229         if (upToDate(status) && (_pos < _ids.size())) {
   230             return (const UnicodeString*)_ids[_pos++];
   231         }
   232         return NULL;
   233     }
   235     virtual void reset(UErrorCode& status) {
   236         if (status == U_ENUM_OUT_OF_SYNC_ERROR) {
   237             status = U_ZERO_ERROR;
   238         }
   239         if (U_SUCCESS(status)) {
   240             _timestamp = _service->getTimestamp();
   241             _pos = 0;
   242             _service->getVisibleIDs(_ids, status);
   243         }
   244     }
   246 public:
   247     static UClassID U_EXPORT2 getStaticClassID(void);
   248     virtual UClassID getDynamicClassID(void) const;
   249 };
   251 ServiceEnumeration::~ServiceEnumeration() {}
   253 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration)
   255 StringEnumeration*
   256 ICULocaleService::getAvailableLocales(void) const
   257 {
   258     return ServiceEnumeration::create(this);
   259 }
   261 const UnicodeString&
   262 ICULocaleService::validateFallbackLocale() const
   263 {
   264     const Locale&     loc    = Locale::getDefault();
   265     ICULocaleService* ncThis = (ICULocaleService*)this;
   266     {
   267         Mutex mutex(&llock);
   268         if (loc != fallbackLocale) {
   269             ncThis->fallbackLocale = loc;
   270             LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
   271             ncThis->clearServiceCache();
   272         }
   273     }
   274     return fallbackLocaleName;
   275 }
   277 ICUServiceKey*
   278 ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
   279 {
   280     return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
   281 }
   283 ICUServiceKey*
   284 ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
   285 {
   286     return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
   287 }
   289 U_NAMESPACE_END
   291 /* !UCONFIG_NO_SERVICE */
   292 #endif

mercurial