diff --git a/icu4c/source/common/icuserv.cpp b/icu4c/source/common/icuserv.cpp index eb792de8c24..0b730a25b52 100644 --- a/icu4c/source/common/icuserv.cpp +++ b/icu4c/source/common/icuserv.cpp @@ -18,235 +18,6 @@ U_NAMESPACE_BEGIN -// A reference counted wrapper for an object. Creation and access is -// through RefHandle. - -#ifdef SERVICE_REFCOUNT - -#include "unicode/strenum.h" - -/* - ****************************************************************** - */ - -class RefCounted { -private: - int32_t _count; - UObject* _obj; - - friend class RefHandle; - - RefCounted(UObject* objectToAdopt) : _count(1), _obj(objectToAdopt) {} - ~RefCounted() { delete _obj; } - void ref() { umtx_atomic_inc(&_count); } - void unref() { if (umtx_atomic_dec(&_count) == 0) { delete this; }} -}; - -/* - ****************************************************************** - */ - -// Reference counted handle for an object -class RefHandle { - RefCounted* _ref; - -public: - RefHandle() : _ref(NULL) {} - RefHandle(UObject* obj) : _ref(new RefCounted(obj)) {} - RefHandle(const RefHandle& rhs) : _ref(NULL) { operator=(rhs); } - ~RefHandle() { if (_ref) _ref->unref(); } - RefHandle& operator=(const RefHandle& rhs) { - if (rhs._ref) rhs._ref->ref(); - if (_ref) _ref->unref(); - _ref = rhs._ref; - } - const UObject* get() const { return _ref ? _ref->_obj : NULL; } -}; - -/* - ****************************************************************** - */ - -// Generic enumeration class with fail-fast behavior. - -class MapEnumeration : public UObject, public StringEnumeration -{ - private: - UChar* _buffer; - int _buflen; - - protected: - const ICUService* _service; - uint32_t _timestamp; - RefHandle _table; - ICUServiceKey* _filter; - int32_t _position; - int32_t _count; - - protected: - MapEnumeration(ICUService* service, int32_t timestamp, RefHandle& table, ICUServiceKey* filter = NULL) - : _buffer(NULL) - , _buflen(0) - , _service(service) - , _timestamp(timestamp) - , _table(table) - , _filter(filter) - , _position(0) - , _count(((const Hashtable*)table.get())->count()) - { - } - - virtual ~MapEnumeration() - { - delete _filter; - } - - int32_t count(UErrorCode& status) const - { - return U_SUCCESS(status) ? _count : 0; - } - - const char* next(UErrorCode& status) { - const UnicodeString* us = snext(status); - if (us) { - int newlen; - for (newlen = us->extract((char*)_buffer, _buflen / sizeof(char), NULL, status); - status == U_STRING_NOT_TERMINATED_WARNING || status == U_BUFFER_OVERFLOW_ERROR;) - { - resizeBuffer((newlen + 1) * sizeof(char)); - status = U_ZERO_ERROR; - } - - if (U_SUCCESS(status)) { - ((char*)_buffer)[newlen] = 0; - return (const char*)_buffer; - } - } - return NULL; - } - - const UChar* unext(UErrorCode& status) { - const UnicodeString* us = snext(status); - if (us) { - int newlen; - for (newlen = us->extract((UChar*)_buffer, _buflen / sizeof(UChar), NULL, status); - status == U_STRING_NOT_TERMINATED_WARNING || status == U_BUFFER_OVERFLOW_ERROR;) - { - resizeBuffer((newlen + 1) * sizeof(UChar)); - status = U_ZERO_ERROR; - } - - if (U_SUCCESS(status)) { - ((UChar*)_buffer)[newlen] = 0; - return (const UChar*)_buffer; - } - } - return NULL; - } - - const UnicodeString* snext(UErrorCode& status) - { - if (U_SUCCESS(status)) { - if (_timestamp != _service->_timestamp) { - status = U_ENUM_OUT_OF_SYNCH_ERROR; - } else { - return internalNext((Hashtable*)_table.get()); - } - } - return NULL; - } - - void reset(UErrorCode& status) - { - if (U_SUCCESS(status)) { - service->reset(this); - } - } - - protected: - virtual const UnicodeString* internalNext(Hashtable* table) = 0; - - private: - void reset(RefHandle& table, int32_t timestamp) - { - _table = table; - _timestamp = timestamp; - _position = 0; - _count = ((const Hashtable*)table.get())->count(); - } - - friend class ICUService; -}; - -/* - ****************************************************************** - */ - -// An enumeration over the visible ids in a service. The ids -// are in the hashtable, which is refcounted, so it will not -// disappear as long as the enumeration exists even if the -// service itself unrefs it. For "fail-fast" behavior the -// enumeration checks the timestamp of the service, but this -// is not a guarantee that the result the client receives will -// still be valid once the function returns. - -class IDEnumeration : public MapEnumeration { -public: - IDEnumeration(ICUService* service, int32_t timestamp, RefHandle& table, ICUServiceKey* filter = NULL) - : MapEnumeration(service, timestamp, table, filter) - { - } - -protected: - const UnicodeString* internalNext(Hashtable* table) { - while (TRUE) { - const UnicodeString* elem = (const UnicodeString*)(table->nextElement(_position).key.pointer); - if (elem == NULL || - _filter == NULL || - _filter->isFallbackOf(*elem)) { - return elem; - } - } - return NULL; - } -}; - -/* - ****************************************************************** - */ - -class DisplayEnumeration : public MapEnumeration { -private: - Locale _locale; - UnicodeString _cache; - -public: - DisplayEnumeration(ICUService* service, int32_t timestamp, RefHandle& table, Locale& locale, ICUServiceKey* filter = NULL) - : MapEnumeration(service, timestamp, table, filter), _locale(locale) - { - } - -protected: - const UnicodeString* internalNext(Hashtable* table) { - while (TRUE) { - UHashElement* elem = table->nextElement(_position); - if (elem == NULL) { - return NULL; - } - const UnicodeString* id = (const UnicodeString*)elem->key.pointer; - const ICUServiceFactory* factory = (const ICUServiceFactory*)elem->value.pointer; - if (_filter == NULL || _filter->isFallbackOf(*id)) { - factory->getDisplayName(*id, cache, locale); - return &cache; - } - } - return NULL; - } -}; - -/* SERVICE_REFCOUNT */ -#endif - /* ****************************************************************** */ diff --git a/icu4c/source/common/icuserv.h b/icu4c/source/common/icuserv.h index 7e2e86a59b3..9651fc2adb5 100644 --- a/icu4c/source/common/icuserv.h +++ b/icu4c/source/common/icuserv.h @@ -42,7 +42,6 @@ class ICUServiceKey; class ICUServiceFactory; class SimpleFactory; class ServiceListener; -class ICUServiceEnumeration; class ICUService; class DNCache;