mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-4127 Fix Hashtable constructors.
X-SVN-Rev: 16422
This commit is contained in:
parent
19e709ced5
commit
349c3b5ad3
10 changed files with 75 additions and 54 deletions
|
@ -332,7 +332,7 @@ void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros
|
|||
|
||||
// otherwise iterate through the string, and recursively permute all the other characters
|
||||
UChar32 cp;
|
||||
Hashtable *subpermute = new Hashtable(FALSE, status);
|
||||
Hashtable *subpermute = new Hashtable(status);
|
||||
/* test for NULL */
|
||||
if (subpermute == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -396,7 +396,7 @@ void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros
|
|||
UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status) {
|
||||
//private String[] getEquivalents(String segment)
|
||||
|
||||
Hashtable *result = new Hashtable(FALSE, status);
|
||||
Hashtable *result = new Hashtable(status);
|
||||
/* test for NULL */
|
||||
if (result == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -414,7 +414,7 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
|
|||
// add only the ones that are canonically equivalent
|
||||
// TODO: optimize by not permuting any class zero.
|
||||
|
||||
Hashtable *permutations = new Hashtable(FALSE, status);
|
||||
Hashtable *permutations = new Hashtable(status);
|
||||
/* test for NULL */
|
||||
if (permutations == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -509,7 +509,7 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
|
|||
Hashtable *CanonicalIterator::getEquivalents2(const UChar *segment, int32_t segLen, UErrorCode &status) {
|
||||
//Hashtable *CanonicalIterator::getEquivalents2(const UnicodeString &segment, int32_t segLen, UErrorCode &status) {
|
||||
|
||||
Hashtable *result = new Hashtable(FALSE, status);
|
||||
Hashtable *result = new Hashtable(status);
|
||||
/* test for NULL */
|
||||
if (result == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -674,7 +674,7 @@ Hashtable *CanonicalIterator::extract(UChar32 comp, const UChar *segment, int32_
|
|||
//if (PROGRESS) printf("Matches\n");
|
||||
|
||||
if (bufLen == 0) {
|
||||
Hashtable *result = new Hashtable(FALSE, status);
|
||||
Hashtable *result = new Hashtable(status);
|
||||
/* test for NULL */
|
||||
if (result == 0) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2001, International Business Machines
|
||||
* Copyright (C) 1997-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* Date Name Description
|
||||
|
@ -27,6 +27,8 @@ U_NAMESPACE_BEGIN
|
|||
class U_COMMON_API Hashtable : public UMemory {
|
||||
UHashtable* hash;
|
||||
|
||||
inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UErrorCode& status);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a hashtable
|
||||
|
@ -35,12 +37,19 @@ public:
|
|||
*/
|
||||
Hashtable(UBool ignoreKeyCase, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Construct a hashtable
|
||||
* @param ignoreKeyCase If true, keys are case insensitive.
|
||||
* @param status Error code
|
||||
*/
|
||||
Hashtable(UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Construct a hashtable, _disregarding any error_. Use this constructor
|
||||
* with caution.
|
||||
* @param ignoreKeyCase if TRUE, keys are case insensitive
|
||||
*/
|
||||
Hashtable(UBool ignoreKeyCase = FALSE);
|
||||
Hashtable();
|
||||
|
||||
/**
|
||||
* Non-virtual destructor; make this virtual if Hashtable is subclassed
|
||||
|
@ -79,31 +88,37 @@ private:
|
|||
* Implementation
|
||||
********************************************************************/
|
||||
|
||||
inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status) :
|
||||
hash(0) {
|
||||
inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
hash = uhash_open(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
||||
: uhash_hashUnicodeString,
|
||||
ignoreKeyCase ? uhash_compareCaselessUnicodeString
|
||||
: uhash_compareUnicodeString,
|
||||
&status);
|
||||
hash = uhash_open(keyHash, keyComp, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
uhash_setKeyDeleter(hash, uhash_deleteUnicodeString);
|
||||
}
|
||||
}
|
||||
|
||||
inline Hashtable::Hashtable(UBool ignoreKeyCase) : hash(0) {
|
||||
inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
|
||||
: hash(0)
|
||||
{
|
||||
init(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
||||
: uhash_hashUnicodeString,
|
||||
ignoreKeyCase ? uhash_compareCaselessUnicodeString
|
||||
: uhash_compareUnicodeString,
|
||||
status);
|
||||
}
|
||||
|
||||
inline Hashtable::Hashtable(UErrorCode& status)
|
||||
: hash(0)
|
||||
{
|
||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, status);
|
||||
}
|
||||
|
||||
inline Hashtable::Hashtable()
|
||||
: hash(0)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
hash = uhash_open(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
||||
: uhash_hashUnicodeString,
|
||||
ignoreKeyCase ? uhash_compareCaselessUnicodeString
|
||||
: uhash_compareUnicodeString,
|
||||
&status);
|
||||
if (U_SUCCESS(status)) {
|
||||
uhash_setKeyDeleter(hash, uhash_deleteUnicodeString);
|
||||
}
|
||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, status);
|
||||
}
|
||||
|
||||
inline Hashtable::~Hashtable() {
|
||||
|
|
|
@ -191,14 +191,15 @@ LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
|
|||
// from ures_openAvailableLocales. The second-level values are
|
||||
// garbage ((void*)1 or other random pointer).
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Hashtable* cache;
|
||||
umtx_lock(NULL);
|
||||
cache = LocaleUtility_cache;
|
||||
umtx_unlock(NULL);
|
||||
|
||||
if (cache == NULL) {
|
||||
cache = new Hashtable();
|
||||
if (cache == NULL) {
|
||||
cache = new Hashtable(status);
|
||||
if (cache == NULL || U_FAILURE(status)) {
|
||||
return NULL; // catastrophic failure; e.g. out of memory
|
||||
}
|
||||
cache->setValueDeleter(uhash_deleteHashtable);
|
||||
|
@ -223,9 +224,8 @@ LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
|
|||
umtx_unlock(NULL);
|
||||
|
||||
if (htp == NULL) {
|
||||
htp = new Hashtable();
|
||||
if (htp) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
htp = new Hashtable(status);
|
||||
if (htp && U_SUCCESS(status)) {
|
||||
CharString cbundleID(bundleID);
|
||||
const char* path = (const char*) cbundleID;
|
||||
if (*path == 0) path = NULL; // empty string => NULL
|
||||
|
|
|
@ -278,7 +278,7 @@ public:
|
|||
const Locale locale;
|
||||
|
||||
DNCache(const Locale& _locale)
|
||||
: cache(FALSE), locale(_locale)
|
||||
: cache(), locale(_locale)
|
||||
{
|
||||
// cache.setKeyDeleter(uhash_deleteUnicodeString);
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUSer
|
|||
XMutex(&ncthis->lock, factory != NULL);
|
||||
|
||||
if (serviceCache == NULL) {
|
||||
ncthis->serviceCache = new Hashtable(FALSE, status);
|
||||
ncthis->serviceCache = new Hashtable(status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete serviceCache;
|
||||
return NULL;
|
||||
|
@ -658,7 +658,7 @@ ICUService::getVisibleIDMap(UErrorCode& status) const {
|
|||
|
||||
ICUService* ncthis = (ICUService*)this; // cast away semantic const
|
||||
if (idCache == NULL) {
|
||||
ncthis->idCache = new Hashtable();
|
||||
ncthis->idCache = new Hashtable(status);
|
||||
if (idCache == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
} else if (factories != NULL) {
|
||||
|
|
|
@ -319,8 +319,8 @@ UScriptCode AnyTransliterator::scriptNameToCode(const UnicodeString& name) {
|
|||
*/
|
||||
void AnyTransliterator::registerIDs() {
|
||||
|
||||
UErrorCode ec;
|
||||
Hashtable seen(TRUE);
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
Hashtable seen(TRUE, ec);
|
||||
|
||||
int32_t sourceCount = Transliterator::_countAvailableSources();
|
||||
for (int32_t s=0; s<sourceCount; ++s) {
|
||||
|
|
|
@ -953,7 +953,7 @@ void TransliteratorParser::parseRules(const UnicodeString& rule,
|
|||
int32_t p = pos;
|
||||
|
||||
TransliteratorIDParser::SingleID* id =
|
||||
TransliteratorIDParser::parseSingleID(rule, p, direction);
|
||||
TransliteratorIDParser::parseSingleID(rule, p, direction, status);
|
||||
if (p != pos && ICU_Utility::parseChar(rule, p, END_OF_RULE)) {
|
||||
// Successful ::ID parse.
|
||||
|
||||
|
|
|
@ -1203,7 +1203,8 @@ void Transliterator::_registerFactory(const UnicodeString& id,
|
|||
void Transliterator::_registerSpecialInverse(const UnicodeString& target,
|
||||
const UnicodeString& inverseTarget,
|
||||
UBool bidirectional) {
|
||||
TransliteratorIDParser::registerSpecialInverse(target, inverseTarget, bidirectional);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
TransliteratorIDParser::registerSpecialInverse(target, inverseTarget, bidirectional, status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -466,8 +466,8 @@ U_CDECL_END
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
TransliteratorRegistry::TransliteratorRegistry(UErrorCode& status) :
|
||||
registry(TRUE),
|
||||
specDAG(TRUE),
|
||||
registry(TRUE, status),
|
||||
specDAG(TRUE, status),
|
||||
availableIDs(status)
|
||||
{
|
||||
registry.setValueDeleter(deleteEntry);
|
||||
|
@ -851,8 +851,8 @@ void TransliteratorRegistry::registerSTV(const UnicodeString& source,
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
Hashtable *targets = (Hashtable*) specDAG.get(source);
|
||||
if (targets == 0) {
|
||||
targets = new Hashtable(TRUE);
|
||||
if (targets == 0) {
|
||||
targets = new Hashtable(TRUE, status);
|
||||
if (U_FAILURE(status) || targets == 0) {
|
||||
return;
|
||||
}
|
||||
targets->setValueDeleter(uhash_deleteUVector);
|
||||
|
|
|
@ -105,7 +105,7 @@ Transliterator* TransliteratorIDParser::SingleID::createInstance() {
|
|||
*/
|
||||
TransliteratorIDParser::SingleID*
|
||||
TransliteratorIDParser::parseSingleID(const UnicodeString& id, int32_t& pos,
|
||||
int32_t dir) {
|
||||
int32_t dir, UErrorCode& status) {
|
||||
|
||||
int32_t start = pos;
|
||||
|
||||
|
@ -167,7 +167,7 @@ TransliteratorIDParser::parseSingleID(const UnicodeString& id, int32_t& pos,
|
|||
if (dir == FORWARD) {
|
||||
single = specsToID(specsA, FORWARD);
|
||||
} else {
|
||||
single = specsToSpecialInverse(*specsA);
|
||||
single = specsToSpecialInverse(*specsA, status);
|
||||
if (single == NULL) {
|
||||
single = specsToID(specsA, REVERSE);
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ UBool TransliteratorIDParser::parseCompoundID(const UnicodeString& id, int32_t d
|
|||
|
||||
UBool sawDelimiter = TRUE;
|
||||
for (;;) {
|
||||
SingleID* single = parseSingleID(id, pos, dir);
|
||||
SingleID* single = parseSingleID(id, pos, dir, ec);
|
||||
if (single == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -637,8 +637,12 @@ void TransliteratorIDParser::STVtoID(const UnicodeString& source,
|
|||
*/
|
||||
void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target,
|
||||
const UnicodeString& inverseTarget,
|
||||
UBool bidirectional) {
|
||||
init();
|
||||
UBool bidirectional,
|
||||
UErrorCode &status) {
|
||||
init(status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If target == inverseTarget then force bidirectional => FALSE
|
||||
if (bidirectional && 0==target.caseCompare(inverseTarget, U_FOLD_CASE_DEFAULT)) {
|
||||
|
@ -649,9 +653,9 @@ void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target,
|
|||
Mutex lock(&LOCK);
|
||||
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
SPECIAL_INVERSES->put(target, new UnicodeString(inverseTarget), ec);
|
||||
SPECIAL_INVERSES->put(target, new UnicodeString(inverseTarget), status);
|
||||
if (bidirectional) {
|
||||
SPECIAL_INVERSES->put(inverseTarget, new UnicodeString(target), ec);
|
||||
SPECIAL_INVERSES->put(inverseTarget, new UnicodeString(target), status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,11 +834,11 @@ TransliteratorIDParser::specsToID(const Specs* specs, int32_t dir) {
|
|||
* 'filter' field of NULL.
|
||||
*/
|
||||
TransliteratorIDParser::SingleID*
|
||||
TransliteratorIDParser::specsToSpecialInverse(const Specs& specs) {
|
||||
TransliteratorIDParser::specsToSpecialInverse(const Specs& specs, UErrorCode &status) {
|
||||
if (0!=specs.source.caseCompare(ANY, U_FOLD_CASE_DEFAULT)) {
|
||||
return NULL;
|
||||
}
|
||||
init();
|
||||
init(status);
|
||||
|
||||
UnicodeString* inverseTarget;
|
||||
|
||||
|
@ -880,12 +884,12 @@ Transliterator* TransliteratorIDParser::createBasicInstance(const UnicodeString&
|
|||
/**
|
||||
* Initialize static memory.
|
||||
*/
|
||||
void TransliteratorIDParser::init() {
|
||||
void TransliteratorIDParser::init(UErrorCode &status) {
|
||||
if (SPECIAL_INVERSES != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
Hashtable* special_inverses = new Hashtable(TRUE);
|
||||
Hashtable* special_inverses = new Hashtable(TRUE, status);
|
||||
special_inverses->setValueDeleter(uhash_deleteUnicodeString);
|
||||
|
||||
umtx_init(&LOCK);
|
||||
|
|
|
@ -135,7 +135,7 @@ class TransliteratorIDParser /* not : public UObject because all methods are sta
|
|||
* @return a SingleID object or null
|
||||
*/
|
||||
static SingleID* parseSingleID(const UnicodeString& id, int32_t& pos,
|
||||
int32_t dir);
|
||||
int32_t dir, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Parse a global filter of the form "[f]" or "([f])", depending
|
||||
|
@ -287,7 +287,8 @@ class TransliteratorIDParser /* not : public UObject because all methods are sta
|
|||
*/
|
||||
static void registerSpecialInverse(const UnicodeString& target,
|
||||
const UnicodeString& inverseTarget,
|
||||
UBool bidirectional);
|
||||
UBool bidirectional,
|
||||
UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Free static memory.
|
||||
|
@ -343,7 +344,7 @@ class TransliteratorIDParser /* not : public UObject because all methods are sta
|
|||
* @return a SingleID or null. Returned object always has
|
||||
* 'filter' field of null.
|
||||
*/
|
||||
static SingleID* specsToSpecialInverse(const Specs& specs);
|
||||
static SingleID* specsToSpecialInverse(const Specs& specs, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Glue method to get around access problems in C++.
|
||||
|
@ -356,7 +357,7 @@ class TransliteratorIDParser /* not : public UObject because all methods are sta
|
|||
/**
|
||||
* Initialize static memory.
|
||||
*/
|
||||
static void init();
|
||||
static void init(UErrorCode &status);
|
||||
|
||||
friend class SingleID;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue