1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius* Copyright (C) 2001-2012, International Business Machines Corporation. 427f654740f2a26ad62a5c155af9199af9e69b889claireho* All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "serv.h" 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#undef SERVICE_REFCOUNT 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// in case we use the refcount stuff 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar ICUServiceKey::PREFIX_DELIMITER = 0x002F; /* '/' */ 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::ICUServiceKey(const UnicodeString& id) 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: _id(id) { 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::~ICUServiceKey() 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeString& 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::getID() const 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return _id; 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::canonicalID(UnicodeString& result) const 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result.append(_id); 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::currentID(UnicodeString& result) const 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return canonicalID(result); 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::currentDescriptor(UnicodeString& result) const 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefix(result); 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(PREFIX_DELIMITER); 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return currentID(result); 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::fallback() 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::isFallbackOf(const UnicodeString& id) const 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return id == _id; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::prefix(UnicodeString& result) const 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::parsePrefix(UnicodeString& result) 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t n = result.indexOf(PREFIX_DELIMITER); 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n < 0) { 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru n = 0; 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.remove(n); 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::parseSuffix(UnicodeString& result) 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t n = result.indexOf(PREFIX_DELIMITER); 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n >= 0) { 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.remove(0, n+1); 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef SERVICE_DEBUG 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::debug(UnicodeString& result) const 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru debugClass(result); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(" id: "); 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(_id); 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey::debugClass(UnicodeString& result) const 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result.append("ICUServiceKey"); 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ICUServiceKey) 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 123103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusICUServiceFactory::~ICUServiceFactory() {} 124103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible) 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: _instance(instanceToAdopt), _id(id), _visible(visible) 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::~SimpleFactory() 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete _instance; 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString temp; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_id == key.currentID(temp)) { 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return service->cloneInstance(_instance); 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_visible) { 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.put(_id, (void*)this, status); // cast away const 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.remove(_id); 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_visible && _id == id) { 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = _id; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.setToBogus(); 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef SERVICE_DEBUG 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::debug(UnicodeString& toAppendTo) const 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru debugClass(toAppendTo); 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toAppendTo.append(" id: "); 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toAppendTo.append(_id); 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toAppendTo.append(", visible: "); 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru toAppendTo.append(_visible ? "T" : "F"); 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleFactory::debugClass(UnicodeString& toAppendTo) const 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo.append("SimpleFactory"); 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleFactory) 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 193103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusServiceListener::~ServiceListener() {} 194103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceListener) 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Record the actual id for this service in the cache, so we can return it 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// even if we succeed later with a different id. 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CacheEntry : public UMemory { 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t refcount; 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString actualDescriptor; 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UObject* service; 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /** 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Releases a reference to the shared resource. 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~CacheEntry() { 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete service; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CacheEntry(const UnicodeString& _actualDescriptor, UObject* _service) 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : refcount(1), actualDescriptor(_actualDescriptor), service(_service) { 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /** 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Instantiation creates an initial reference, so don't call this 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * unless you're creating a new pointer to this. Management of 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that pointer will have to know how to deal with refcounts. 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return true if the resource has not already been released. 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CacheEntry* ref() { 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++refcount; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return this; 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /** 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Destructions removes a reference, so don't call this unless 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * you're removing pointer to this somewhere. Management of that 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * pointer will have to know how to deal with refcounts. Once 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the refcount drops to zero, the resource is released. Return 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * false if the resouce has been released. 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CacheEntry* unref() { 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((--refcount) == 0) { 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete this; 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return this; 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /** 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return TRUE if there is at least one reference to this and the 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * resource has not been released. 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool isShared() const { 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return refcount > 1; 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// UObjectDeleter for serviceCache 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerucacheDeleter(void* obj) { 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_NAMESPACE_USE ((CacheEntry*)obj)->unref(); 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Deleter for UObjects 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerudeleteUObject(void *obj) { 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_NAMESPACE_USE delete (UObject*) obj; 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass DNCache : public UMemory { 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Hashtable cache; 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale locale; 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DNCache(const Locale& _locale) 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : cache(), locale(_locale) 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // cache.setKeyDeleter(uprv_deleteUObject); 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringPair* 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringPair::create(const UnicodeString& displayName, 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& id, 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringPair* sp = new StringPair(displayName, id); 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (sp == NULL || sp->isBogus()) { 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete sp; 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return sp; 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringPair::isBogus() const { 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return displayName.isBogus() || id.isBogus(); 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringPair::StringPair(const UnicodeString& _displayName, 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& _id) 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: displayName(_displayName) 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, id(_id) 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuserv_deleteStringPair(void *obj) { 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_NAMESPACE_USE delete (StringPair*) obj; 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************** 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 33454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex lock = U_MUTEX_INITIALIZER; 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::ICUService() 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: name() 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, timestamp(0) 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, factories(NULL) 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, serviceCache(NULL) 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, idCache(NULL) 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, dnCache(NULL) 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::ICUService(const UnicodeString& newName) 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: name(newName) 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, timestamp(0) 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, factories(NULL) 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, serviceCache(NULL) 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, idCache(NULL) 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru, dnCache(NULL) 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::~ICUService() 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Mutex mutex(&lock); 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clearCaches(); 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete factories; 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru factories = NULL; 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::get(const UnicodeString& descriptor, UErrorCode& status) const 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return get(descriptor, NULL, status); 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UObject* result = NULL; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceKey* key = createKey(&descriptor, status); 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (key) { 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = getKey(*key, actualReturn, status); 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete key; 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getKey(ICUServiceKey& key, UErrorCode& status) const 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getKey(key, NULL, status); 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// this is a vector that subclasses of ICUService can override to further customize the result object 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// before returning it. All other public get functions should call this one. 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getKey(key, actualReturn, NULL, status); 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// make it possible to call reentrantly on systems that don't have reentrant mutexes. 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// we can use this simple approach since we know the situation where we're calling 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// reentrantly even without knowing the thread. 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass XMutex : public UMemory { 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 40454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius inline XMutex(UMutex *mutex, UBool reentering) 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : fMutex(mutex) 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , fActive(!reentering) 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fActive) umtx_lock(fMutex); 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline ~XMutex() { 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fActive) umtx_unlock(fMutex); 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 41554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UMutex *fMutex; 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool fActive; 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct UVectorDeleter { 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UVector* _obj; 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UVectorDeleter() : _obj(NULL) {} 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~UVectorDeleter() { delete _obj; } 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// called only by factories, treat as private 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUServiceFactory* factory, UErrorCode& status) const 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isDefault()) { 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handleDefault(key, actualReturn, status); 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUService* ncthis = (ICUService*)this; // cast away semantic const 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CacheEntry* result = NULL; 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // The factory list can't be modified until we're done, 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // otherwise we might update the cache with an invalid result. 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // The cache has to stay in synch with the factory list. 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ICU doesn't have monitors so we can't use rw locks, so 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // we single-thread everything using this service, for now. 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if factory is not null, we're calling from within the mutex, 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and since some unix machines don't have reentrant mutexes we 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // need to make sure not to try to lock it again. 450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho XMutex mutex(&lock, factory != NULL); 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (serviceCache == NULL) { 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ncthis->serviceCache = new Hashtable(status); 45485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (ncthis->serviceCache == NULL) { 45585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 45685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete serviceCache; 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru serviceCache->setValueDeleter(cacheDeleter); 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString currentDescriptor; 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UVectorDeleter cacheDescriptorList; 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool putInCache = FALSE; 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t startIndex = 0; 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t limit = factories->size(); 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool cacheResult = TRUE; 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factory != NULL) { 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i = 0; i < limit; ++i) { 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factory == (const ICUServiceFactory*)factories->elementAt(i)) { 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru startIndex = i + 1; 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (startIndex == 0) { 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // throw new InternalError("Factory " + factory + "not registered with service: " + this); 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cacheResult = FALSE; 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru currentDescriptor.remove(); 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru key.currentDescriptor(currentDescriptor); 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = (CacheEntry*)serviceCache->get(currentDescriptor); 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result != NULL) { 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // first test of cache failed, so we'll have to update 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the cache if we eventually succeed-- that is, if we're 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // going to update the cache at all. 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru putInCache = TRUE; 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t index = startIndex; 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (index < limit) { 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceFactory* f = (ICUServiceFactory*)factories->elementAt(index++); 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UObject* service = f->create(key, this, status); 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete service; 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (service != NULL) { 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = new CacheEntry(currentDescriptor, service); 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result == NULL) { 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete service; 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto outerEnd; 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // prepare to load the cache with all additional ids that 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // will resolve to result, assuming we'll succeed. We 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // don't want to keep querying on an id that's going to 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // fallback to the one that succeeded, we want to hit the 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // cache the first time next goaround. 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cacheDescriptorList._obj == NULL) { 526103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius cacheDescriptorList._obj = new UVector(uprv_deleteUObject, NULL, 5, status); 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString* idToCache = new UnicodeString(currentDescriptor); 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (idToCache == NULL || idToCache->isBogus()) { 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cacheDescriptorList._obj->addElement(idToCache, status); 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while (key.fallback()); 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruouterEnd: 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result != NULL) { 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (putInCache && cacheResult) { 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru serviceCache->put(result->actualDescriptor, result, status); 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete result; 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cacheDescriptorList._obj != NULL) { 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i = cacheDescriptorList._obj->size(); --i >= 0;) { 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString* desc = (UnicodeString*)cacheDescriptorList._obj->elementAt(i); 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru serviceCache->put(*desc, result, status); 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete result; 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result->ref(); 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cacheDescriptorList._obj->removeElementAt(i); 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (actualReturn != NULL) { 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // strip null prefix 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result->actualDescriptor.indexOf((UChar)0x2f) == 0) { // U+002f=slash (/) 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru actualReturn->remove(); 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru actualReturn->append(result->actualDescriptor, 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1, 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result->actualDescriptor.length() - 1); 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *actualReturn = result->actualDescriptor; 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (actualReturn->isBogus()) { 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete result; 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UObject* service = cloneInstance(result->service); 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (putInCache && !cacheResult) { 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete result; 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return service; 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handleDefault(key, actualReturn, status); 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject* 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::handleDefault(const ICUServiceKey& /* key */, UnicodeString* /* actualIDReturn */, UErrorCode& /* status */) const 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUVector& 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getVisibleIDs(UVector& result, UErrorCode& status) const { 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getVisibleIDs(result, NULL, status); 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUVector& 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.removeAllElements(); 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Mutex mutex(&lock); 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Hashtable* map = getVisibleIDMap(status); 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (map != NULL) { 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceKey* fallbackKey = createKey(matchID, status); 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t pos = -1;;) { 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UHashElement* e = map->nextElement(pos); 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (e == NULL) { 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* id = (const UnicodeString*)e->key.pointer; 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fallbackKey != NULL) { 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!fallbackKey->isFallbackOf(*id)) { 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString* idClone = new UnicodeString(*id); 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (idClone == NULL || idClone->isBogus()) { 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete idClone; 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.addElement(idClone, status); 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete idClone; 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fallbackKey; 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.removeAllElements(); 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst Hashtable* 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getVisibleIDMap(UErrorCode& status) const { 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) return NULL; 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // must only be called when lock is already held 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUService* ncthis = (ICUService*)this; // cast away semantic const 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (idCache == NULL) { 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ncthis->idCache = new Hashtable(status); 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (idCache == NULL) { 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (factories != NULL) { 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t pos = factories->size(); --pos >= 0;) { 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceFactory* f = (ICUServiceFactory*)factories->elementAt(pos); 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru f->updateVisibleIDs(*idCache, status); 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete idCache; 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ncthis->idCache = NULL; 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return idCache; 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getDisplayName(const UnicodeString& id, UnicodeString& result) const 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getDisplayName(id, result, Locale::getDefault()); 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 694b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Mutex mutex(&lock); 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Hashtable* map = getVisibleIDMap(status); 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (map != NULL) { 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceFactory* f = (ICUServiceFactory*)map->get(id); 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (f != NULL) { 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru f->getDisplayName(id, locale, result); 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // fallback 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceKey* fallbackKey = createKey(&id, status); 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (fallbackKey->fallback()) { 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString us; 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fallbackKey->currentID(us); 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru f = (ICUServiceFactory*)map->get(us); 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (f != NULL) { 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru f->getDisplayName(id, locale, result); 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fallbackKey; 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete fallbackKey; 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.setToBogus(); 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUVector& 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getDisplayNames(UVector& result, UErrorCode& status) const 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getDisplayNames(result, Locale::getDefault(), NULL, status); 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUVector& 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getDisplayNames(UVector& result, const Locale& locale, UErrorCode& status) const 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getDisplayNames(result, locale, NULL, status); 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUVector& 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getDisplayNames(UVector& result, 738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& locale, 739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* matchID, 740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.removeAllElements(); 743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.setDeleter(userv_deleteStringPair); 744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUService* ncthis = (ICUService*)this; // cast away semantic const 746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Mutex mutex(&lock); 747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (dnCache != NULL && dnCache->locale != locale) { 749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete dnCache; 750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ncthis->dnCache = NULL; 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (dnCache == NULL) { 754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Hashtable* m = getVisibleIDMap(status); 755103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 756103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 758103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ncthis->dnCache = new DNCache(locale); 759103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (dnCache == NULL) { 760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 762103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 764103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t pos = -1; 765103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UHashElement* entry = NULL; 766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while ((entry = m->nextElement(pos)) != NULL) { 767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString* id = (const UnicodeString*)entry->key.pointer; 768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer; 769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString dname; 770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius f->getDisplayName(*id, locale, dname); 771103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (dname.isBogus()) { 772103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 773103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 774103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap 775103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 776103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius continue; 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 779103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete dnCache; 780103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ncthis->dnCache = NULL; 781103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceKey* matchKey = createKey(matchID, status); 78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* To ensure that all elements in the hashtable are iterated, set pos to -1. 78885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * nextElement(pos) will skip the position at pos and begin the iteration 78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * at the next position, which in this case will be 0. 79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 79185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t pos = -1; 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UHashElement *entry = NULL; 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while ((entry = dnCache->cache.nextElement(pos)) != NULL) { 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* id = (const UnicodeString*)entry->value.pointer; 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (matchKey != NULL && !matchKey->isFallbackOf(*id)) { 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru continue; 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* dn = (const UnicodeString*)entry->key.pointer; 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringPair* sp = StringPair::create(*id, *dn, status); 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.addElement(sp, status); 801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.removeAllElements(); 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete matchKey; 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UErrorCode& status) 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return registerInstance(objToAdopt, id, TRUE, status); 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status) 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceKey* key = createKey(&id, status); 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (key != NULL) { 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString canonicalID; 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru key->canonicalID(canonicalID); 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete key; 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceFactory* f = createSimpleFactory(objToAdopt, canonicalID, visible, status); 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (f != NULL) { 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return registerFactory(f, status); 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete objToAdopt; 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceFactory* 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::createSimpleFactory(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status) 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((objToAdopt != NULL) && (!id.isBogus())) { 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new SimpleFactory(objToAdopt, id, visible); 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status) 849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status) && factoryToAdopt != NULL) { 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Mutex mutex(&lock); 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factories == NULL) { 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru factories = new UVector(deleteUObject, NULL, status); 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete factories; 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru factories->insertElementAt(factoryToAdopt, 0, status); 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clearCaches(); 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete factoryToAdopt; 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru factoryToAdopt = NULL; 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factoryToAdopt != NULL) { 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru notifyChanged(); 871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (URegistryKey)factoryToAdopt; 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::unregister(URegistryKey rkey, UErrorCode& status) 878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ICUServiceFactory *factory = (ICUServiceFactory*)rkey; 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool result = FALSE; 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factory != NULL && factories != NULL) { 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Mutex mutex(&lock); 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factories->removeElement(factory)) { 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clearCaches(); 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = TRUE; 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete factory; 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result) { 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru notifyChanged(); 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::reset() 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Mutex mutex(&lock); 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru reInitializeFactories(); 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru clearCaches(); 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru notifyChanged(); 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::reInitializeFactories() 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (factories != NULL) { 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru factories->removeAllElements(); 914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::isDefault() const 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return countFactories() == 0; 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey* 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::createKey(const UnicodeString* id, UErrorCode& status) const 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (U_FAILURE(status) || id == NULL) ? NULL : new ICUServiceKey(*id); 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::clearCaches() 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // callers synchronize before use 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++timestamp; 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete dnCache; 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dnCache = NULL; 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete idCache; 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru idCache = NULL; 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete serviceCache; serviceCache = NULL; 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::clearServiceCache() 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // callers synchronize before use 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete serviceCache; serviceCache = NULL; 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::acceptsListener(const EventListener& l) const 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 95127f654740f2a26ad62a5c155af9199af9e69b889claireho return dynamic_cast<const ServiceListener*>(&l) != NULL; 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::notifyListener(EventListener& l) const 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((ServiceListener&)l).serviceChanged(*this); 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getName(UnicodeString& result) const 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result.append(name); 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::countFactories() const 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return factories == NULL ? 0 : factories->size(); 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUService::getTimestamp() const 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return timestamp; 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* UCONFIG_NO_SERVICE */ 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 982