mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-4741 make compare functions for Hashtable and StringEnumeration general
X-SVN-Rev: 18788
This commit is contained in:
parent
18d6eeb8dc
commit
b70227e2c7
25 changed files with 257 additions and 210 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2004, International Business Machines
|
||||
* Copyright (C) 1997-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* Date Name Description
|
||||
|
@ -27,7 +27,7 @@ U_NAMESPACE_BEGIN
|
|||
class U_COMMON_API Hashtable : public UMemory {
|
||||
UHashtable* hash;
|
||||
|
||||
inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UErrorCode& status);
|
||||
inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -37,6 +37,14 @@ public:
|
|||
*/
|
||||
Hashtable(UBool ignoreKeyCase, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Construct a hashtable
|
||||
* @param keyComp Compartor for comparing the keys
|
||||
* @param valueComp Compartor for comparing the values
|
||||
* @param status Error code
|
||||
*/
|
||||
Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Construct a hashtable
|
||||
* @param status Error code
|
||||
|
@ -76,7 +84,12 @@ public:
|
|||
const UHashElement* find(const UnicodeString& key) const;
|
||||
|
||||
const UHashElement* nextElement(int32_t& pos) const;
|
||||
|
||||
UKeyComparator* setKeyCompartor(UKeyComparator*keyComp);
|
||||
|
||||
UValueComparator* setValueCompartor(UValueComparator* valueComp);
|
||||
|
||||
UBool equals(const Hashtable& that) const;
|
||||
private:
|
||||
Hashtable(const Hashtable &other); // forbid copying of this class
|
||||
Hashtable &operator=(const Hashtable &other); // forbid copying of this class
|
||||
|
@ -86,16 +99,21 @@ private:
|
|||
* Implementation
|
||||
********************************************************************/
|
||||
|
||||
inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp, UErrorCode& status) {
|
||||
inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
hash = uhash_open(keyHash, keyComp, &status);
|
||||
hash = uhash_open(keyHash, keyComp, valueComp, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
uhash_setKeyDeleter(hash, uhash_deleteUnicodeString);
|
||||
}
|
||||
}
|
||||
|
||||
inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp,
|
||||
UErrorCode& status): hash(0){
|
||||
init( uhash_hashUnicodeString, keyComp, valueComp, status);
|
||||
}
|
||||
inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
|
||||
: hash(0)
|
||||
{
|
||||
|
@ -103,20 +121,21 @@ inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
|
|||
: uhash_hashUnicodeString,
|
||||
ignoreKeyCase ? uhash_compareCaselessUnicodeString
|
||||
: uhash_compareUnicodeString,
|
||||
NULL,
|
||||
status);
|
||||
}
|
||||
|
||||
inline Hashtable::Hashtable(UErrorCode& status)
|
||||
: hash(0)
|
||||
{
|
||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, status);
|
||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
|
||||
}
|
||||
|
||||
inline Hashtable::Hashtable()
|
||||
: hash(0)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, status);
|
||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
|
||||
}
|
||||
|
||||
inline Hashtable::~Hashtable() {
|
||||
|
@ -170,6 +189,17 @@ inline void Hashtable::removeAll(void) {
|
|||
uhash_removeAll(hash);
|
||||
}
|
||||
|
||||
inline UKeyComparator* Hashtable::setKeyCompartor(UKeyComparator*keyComp){
|
||||
return uhash_setKeyComparator(hash, keyComp);
|
||||
}
|
||||
|
||||
inline UValueComparator* Hashtable::setValueCompartor(UValueComparator* valueComp){
|
||||
return uhash_setValueComparator(hash, valueComp);
|
||||
}
|
||||
|
||||
inline UBool Hashtable::equals(const Hashtable& that)const{
|
||||
return uhash_equals(hash, that.hash);
|
||||
}
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -160,7 +160,7 @@ void locale_set_default_internal(const char *id)
|
|||
umtx_unlock(NULL);
|
||||
if (hashTableNeedsInit) {
|
||||
status = U_ZERO_ERROR;
|
||||
UHashtable *tHashTable = uhash_open(uhash_hashChars, uhash_compareChars, &status);
|
||||
UHashtable *tHashTable = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb)
|
|||
}
|
||||
|
||||
fSymbolTable = new RBBISymbolTable(this, rb->fRules, *rb->fStatus);
|
||||
fSetTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, rb->fStatus);
|
||||
fSetTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, rb->fStatus);
|
||||
uhash_setValueDeleter(fSetTable, RBBISetTable_deleter);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ RBBISymbolTable::RBBISymbolTable(RBBIRuleScanner *rs, const UnicodeString &rules
|
|||
fHashTable = NULL;
|
||||
fCachedSetLookup = NULL;
|
||||
|
||||
fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, &status);
|
||||
fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status);
|
||||
// uhash_open checks status
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
|
|
|
@ -374,7 +374,7 @@ ucnv_shareConverterData(UConverterSharedData * data)
|
|||
|
||||
if (SHARED_DATA_HASHTABLE == NULL)
|
||||
{
|
||||
SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars,
|
||||
SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars, NULL,
|
||||
ucnv_io_countTotalAliases(&err),
|
||||
&err);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
|
|
|
@ -218,7 +218,7 @@ static UHashtable *udata_getHashTable() {
|
|||
return gCommonDataCache;
|
||||
}
|
||||
|
||||
tHT = uhash_open(uhash_hashChars, uhash_compareChars, &err);
|
||||
tHT = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
|
||||
uhash_setValueDeleter(tHT, DataCacheElement_deleter);
|
||||
|
||||
umtx_lock(NULL);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2004, International Business Machines
|
||||
* Copyright (C) 1997-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* Date Name Description
|
||||
|
@ -140,7 +140,9 @@ static const float RESIZE_POLICY_RATIO_TABLE[6] = {
|
|||
* PRIVATE Prototypes
|
||||
********************************************************************/
|
||||
|
||||
static UHashtable* _uhash_create(UHashFunction *keyHash, UKeyComparator *keyComp,
|
||||
static UHashtable* _uhash_create(UHashFunction *keyHash,
|
||||
UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp,
|
||||
int32_t primeIndex, UErrorCode *status);
|
||||
|
||||
static void _uhash_allocate(UHashtable *hash, int32_t primeIndex,
|
||||
|
@ -174,14 +176,18 @@ static void _uhash_internalSetResizePolicy(UHashtable *hash, enum UHashResizePol
|
|||
********************************************************************/
|
||||
|
||||
U_CAPI UHashtable* U_EXPORT2
|
||||
uhash_open(UHashFunction *keyHash, UKeyComparator *keyComp,
|
||||
uhash_open(UHashFunction *keyHash,
|
||||
UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp,
|
||||
UErrorCode *status) {
|
||||
|
||||
return _uhash_create(keyHash, keyComp, 3, status);
|
||||
return _uhash_create(keyHash, keyComp, valueComp, 3, status);
|
||||
}
|
||||
|
||||
U_CAPI UHashtable* U_EXPORT2
|
||||
uhash_openSize(UHashFunction *keyHash, UKeyComparator *keyComp,
|
||||
uhash_openSize(UHashFunction *keyHash,
|
||||
UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp,
|
||||
int32_t size,
|
||||
UErrorCode *status) {
|
||||
|
||||
|
@ -191,7 +197,7 @@ uhash_openSize(UHashFunction *keyHash, UKeyComparator *keyComp,
|
|||
++i;
|
||||
}
|
||||
|
||||
return _uhash_create(keyHash, keyComp, i, status);
|
||||
return _uhash_create(keyHash, keyComp, valueComp, i, status);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
|
@ -224,6 +230,12 @@ uhash_setKeyComparator(UHashtable *hash, UKeyComparator *fn) {
|
|||
hash->keyComparator = fn;
|
||||
return result;
|
||||
}
|
||||
U_CAPI UValueComparator *U_EXPORT2
|
||||
uhash_setValueComparator(UHashtable *hash, UValueComparator *fn){
|
||||
UValueComparator *result = hash->valueComparator;
|
||||
hash->valueComparator = fn;
|
||||
return result;
|
||||
}
|
||||
|
||||
U_CAPI UObjectDeleter *U_EXPORT2
|
||||
uhash_setKeyDeleter(UHashtable *hash, UObjectDeleter *fn) {
|
||||
|
@ -491,6 +503,48 @@ uhash_hashIChars(const UHashTok key) {
|
|||
STRING_HASH(uint8_t, key.pointer, uprv_strlen((char*)p), uprv_tolower(*p));
|
||||
}
|
||||
|
||||
U_CAPI UBool U_EXPORT2
|
||||
uhash_equals(const UHashtable* hash1, const UHashtable* hash2){
|
||||
|
||||
int32_t count1, count2, pos, i;
|
||||
|
||||
if(hash1==hash2){
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(hash1==NULL || hash2==NULL){
|
||||
return FALSE;
|
||||
}
|
||||
/* make sure that we are comparing 2 hashes of the same type */
|
||||
if( hash1->keyComparator != hash2->keyComparator ||
|
||||
hash2->valueComparator != hash2->valueComparator){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
count1 = uhash_count(hash1);
|
||||
count2 = uhash_count(hash2);
|
||||
if(count1!=count2){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pos=-1;
|
||||
for(i=0; i<count1; i++){
|
||||
const UHashElement* elem1 = uhash_nextElement(hash1, &pos);
|
||||
const UHashTok key1 = elem1->key;
|
||||
const UHashTok val1 = elem1->value;
|
||||
/* here the keys are not compared, instead the key form hash1 is used to fetch
|
||||
* value from hash2. If the hashes are equal then then both hashes should
|
||||
* contain equal values for the same key!
|
||||
*/
|
||||
const UHashElement* elem2 = _uhash_find(hash2, key1, hash2->keyHasher(key1));
|
||||
const UHashTok val2 = elem2->value;
|
||||
if(hash1->valueComparator(val1, val2)==FALSE){
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* PUBLIC Comparator Functions
|
||||
********************************************************************/
|
||||
|
@ -574,7 +628,9 @@ uhash_freeBlock(void *obj) {
|
|||
********************************************************************/
|
||||
|
||||
static UHashtable*
|
||||
_uhash_create(UHashFunction *keyHash, UKeyComparator *keyComp,
|
||||
_uhash_create(UHashFunction *keyHash,
|
||||
UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp,
|
||||
int32_t primeIndex,
|
||||
UErrorCode *status) {
|
||||
UHashtable *result;
|
||||
|
@ -589,10 +645,11 @@ _uhash_create(UHashFunction *keyHash, UKeyComparator *keyComp,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
result->keyHasher = keyHash;
|
||||
result->keyComparator = keyComp;
|
||||
result->keyDeleter = NULL;
|
||||
result->valueDeleter = NULL;
|
||||
result->keyHasher = keyHash;
|
||||
result->keyComparator = keyComp;
|
||||
result->valueComparator = valueComp;
|
||||
result->keyDeleter = NULL;
|
||||
result->valueDeleter = NULL;
|
||||
_uhash_internalSetResizePolicy(result, U_GROW);
|
||||
|
||||
_uhash_allocate(result, primeIndex, status);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2004, International Business Machines
|
||||
* Copyright (C) 1997-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* Date Name Description
|
||||
|
@ -117,7 +117,14 @@ typedef int32_t U_CALLCONV UHashFunction(const UHashTok key);
|
|||
*/
|
||||
typedef UBool U_CALLCONV UKeyComparator(const UHashTok key1,
|
||||
const UHashTok key2);
|
||||
|
||||
/**
|
||||
* A key comparison function.
|
||||
* @param val1 A key stored in a hashtable
|
||||
* @param val2 A key stored in a hashtable
|
||||
* @return TRUE if the two keys are equal.
|
||||
*/
|
||||
typedef UBool U_CALLCONV UValueComparator(const UHashTok val1,
|
||||
const UHashTok val2);
|
||||
/**
|
||||
* A function called by <TT>uhash_remove</TT>,
|
||||
* <TT>uhash_close</TT>, or <TT>uhash_put</TT> to delete
|
||||
|
@ -169,6 +176,8 @@ struct UHashtable {
|
|||
* Never null. */
|
||||
UKeyComparator *keyComparator; /* Compares keys for equality.
|
||||
* Never null. */
|
||||
UValueComparator *valueComparator; /* Compares the values for equality */
|
||||
|
||||
UObjectDeleter *keyDeleter; /* Deletes keys when required.
|
||||
* If NULL won't do anything */
|
||||
UObjectDeleter *valueDeleter; /* Deletes values when required.
|
||||
|
@ -195,6 +204,7 @@ U_CDECL_END
|
|||
U_CAPI UHashtable* U_EXPORT2
|
||||
uhash_open(UHashFunction *keyHash,
|
||||
UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp,
|
||||
UErrorCode *status);
|
||||
|
||||
/**
|
||||
|
@ -211,6 +221,7 @@ uhash_open(UHashFunction *keyHash,
|
|||
U_CAPI UHashtable* U_EXPORT2
|
||||
uhash_openSize(UHashFunction *keyHash,
|
||||
UKeyComparator *keyComp,
|
||||
UValueComparator *valueComp,
|
||||
int32_t size,
|
||||
UErrorCode *status);
|
||||
|
||||
|
@ -242,6 +253,16 @@ uhash_setKeyHasher(UHashtable *hash, UHashFunction *fn);
|
|||
U_CAPI UKeyComparator *U_EXPORT2
|
||||
uhash_setKeyComparator(UHashtable *hash, UKeyComparator *fn);
|
||||
|
||||
/**
|
||||
* Set the function used to compare values. The default comparison is a
|
||||
* void* pointer comparison.
|
||||
* @param hash The UHashtable to set
|
||||
* @param fn the function to be used compare keys; must not be NULL
|
||||
* @return the previous key comparator; non-NULL
|
||||
*/
|
||||
U_CAPI UValueComparator *U_EXPORT2
|
||||
uhash_setValueComparator(UHashtable *hash, UValueComparator *fn);
|
||||
|
||||
/**
|
||||
* Set the function used to delete keys. If this function pointer is
|
||||
* NULL, this hashtable does not delete keys. If it is non-NULL, this
|
||||
|
@ -676,4 +697,13 @@ uhash_deleteUVector(void *obj);
|
|||
U_CAPI void U_EXPORT2
|
||||
uhash_freeBlock(void *obj);
|
||||
|
||||
/**
|
||||
* Checks if the given hash tables are equal or not.
|
||||
* @param hash1
|
||||
* @param hash2
|
||||
* @return true if the hashtables are equal and false if not.
|
||||
*/
|
||||
U_CAPI UBool U_EXPORT2
|
||||
uhash_equals(const UHashtable* hash1, const UHashtable* hash2);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -184,6 +184,23 @@ public:
|
|||
*/
|
||||
virtual void reset(UErrorCode& status) = 0;
|
||||
|
||||
/**
|
||||
* Compares this enumeration to other to check if both are equal
|
||||
*
|
||||
* @param Other string enumeration to compare this object to
|
||||
* @return TRUE if the enumerations are equal. FALSE if not.
|
||||
* @draft ICU 3.6
|
||||
*/
|
||||
virtual UBool operator==(const StringEnumeration& that)const;
|
||||
/**
|
||||
* Compares this enumeration to other to check if both are not equal
|
||||
*
|
||||
* @param Other string enumeration to compare this object to
|
||||
* @return TRUE if the enumerations are equal. FALSE if not.
|
||||
* @draft ICU 3.6
|
||||
*/
|
||||
virtual UBool operator!=(const StringEnumeration& that)const {return !operator==(that);};
|
||||
|
||||
protected:
|
||||
/**
|
||||
* UnicodeString field for use with default implementations and subclasses.
|
||||
|
|
|
@ -214,7 +214,7 @@ static void initCache(UErrorCode *status) {
|
|||
makeCache = (cache == NULL);
|
||||
umtx_unlock(&resbMutex);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, status);
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ initCache(UErrorCode *status) {
|
|||
makeCache = (SHARED_DATA_HASHTABLE == NULL);
|
||||
umtx_unlock(&usprepMutex);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, status);
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2002-2004, International Business Machines
|
||||
* Copyright (c) 2002-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
|
@ -111,6 +111,10 @@ StringEnumeration::setChars(const char *s, int32_t length, UErrorCode &status) {
|
|||
|
||||
return NULL;
|
||||
}
|
||||
UBool
|
||||
StringEnumeration::operator==(const StringEnumeration& that)const{
|
||||
return getDynamicClassID() == that.getDynamicClassID();
|
||||
}
|
||||
|
||||
// UStringEnumeration implementation --------------------------------------- ***
|
||||
|
||||
|
@ -311,3 +315,4 @@ uenum_openCharStringsEnumeration(const char** strings, int32_t count,
|
|||
return (UEnumeration*) result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ AnyTransliterator::AnyTransliterator(const UnicodeString& id,
|
|||
Transliterator(id, NULL),
|
||||
targetScript(theTargetScript)
|
||||
{
|
||||
cache = uhash_open(uhash_hashLong, uhash_compareLong, &ec);
|
||||
cache = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &ec);
|
||||
uhash_setValueDeleter(cache, _deleteTransliterator);
|
||||
|
||||
target = theTarget;
|
||||
|
@ -205,7 +205,7 @@ AnyTransliterator::AnyTransliterator(const AnyTransliterator& o) :
|
|||
{
|
||||
// Don't copy the cache contents
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
cache = uhash_open(uhash_hashLong, uhash_compareLong, &ec);
|
||||
cache = uhash_open(uhash_hashLong, uhash_compareLong, NULL, &ec);
|
||||
uhash_setValueDeleter(cache, _deleteTransliterator);
|
||||
}
|
||||
|
||||
|
|
|
@ -1543,7 +1543,7 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro
|
|||
}
|
||||
|
||||
CalendarCache::CalendarCache(int32_t size, UErrorCode &status) {
|
||||
fTable = uhash_openSize(uhash_hashLong, uhash_compareLong, size, &status);
|
||||
fTable = uhash_openSize(uhash_hashLong, uhash_compareLong, NULL, size, &status);
|
||||
U_DEBUG_ASTRO_MSG(("%p: Opening.\n", fTable));
|
||||
}
|
||||
|
||||
|
|
|
@ -435,27 +435,15 @@ DateFormatSymbols::operator==(const DateFormatSymbols& other) const
|
|||
return FALSE;
|
||||
}
|
||||
}else{
|
||||
if(hashCompare(fZoneStringsHash, other.fZoneStringsHash) == FALSE){
|
||||
if(fZoneStringsHash->equals(*other.fZoneStringsHash) == FALSE){
|
||||
return FALSE;
|
||||
}
|
||||
// we always make sure that we update the enumeration when the hash is
|
||||
// updated. So we can be sure that once we compare the hashes the
|
||||
// enumerations are also equal
|
||||
//if(stringEnumCompare(fZoneIDEnumeration, other.fZoneIDEnumeration)==FALSE){
|
||||
// return FALSE;
|
||||
//}
|
||||
}
|
||||
// since fZoneStrings data member is deprecated .. and may not be initialized
|
||||
// so don't compare them
|
||||
// fZoneStringsRowCount == other.fZoneStringsRowCount &&
|
||||
//fZoneStringsColCount == other.fZoneStringsColCount
|
||||
//if (fZoneStrings == other.fZoneStrings) return TRUE;
|
||||
//
|
||||
//for (int32_t row=0; row<fZoneStringsRowCount; ++row)
|
||||
//{
|
||||
// if (!arrayCompare(fZoneStrings[row], other.fZoneStrings[row], fZoneStringsColCount))
|
||||
// return FALSE;
|
||||
//}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -826,13 +814,13 @@ DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t r
|
|||
// since deleting a 2-d array is a pain in the butt, we offload that task to
|
||||
// a separate function
|
||||
disposeZoneStrings();
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
// we always own the new list, which we create here (we duplicate rather
|
||||
// than adopting the list passed in)
|
||||
fZoneStringsRowCount = rowCount;
|
||||
fZoneStringsColCount = columnCount;
|
||||
createZoneStrings((const UnicodeString**)strings);
|
||||
initZoneStrings((const UnicodeString**)strings, rowCount,columnCount);
|
||||
initZoneStrings((const UnicodeString**)strings, rowCount,columnCount, status);
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
@ -1053,8 +1041,8 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
|||
weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
|
||||
fWeekdaysCount = ures_getSize(weekdaysData);
|
||||
fWeekdays = new UnicodeString[fWeekdaysCount+1];
|
||||
/* test for NULL */
|
||||
if (fWeekdays == 0) {
|
||||
/* pin the blame on system. If we cannot get a chunk of memory .. the system is dying!*/
|
||||
if (fWeekdays == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -1226,7 +1214,6 @@ DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const
|
|||
return locBased.getLocale(type, status);
|
||||
}
|
||||
|
||||
|
||||
class TimeZoneKeysEnumeration : public StringEnumeration {
|
||||
private:
|
||||
UnicodeString* strings;
|
||||
|
@ -1298,7 +1285,7 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
/* this method is for thread safe iteration */
|
||||
const UnicodeString* snext(int32_t& pos, UErrorCode& status) {
|
||||
const UnicodeString* snext(int32_t& pos, UErrorCode& status)const {
|
||||
if(U_FAILURE(status)){
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1312,7 +1299,44 @@ public:
|
|||
current = 0;
|
||||
|
||||
}
|
||||
virtual UBool operator==(const StringEnumeration& that)const{
|
||||
return ((this == &that) ||
|
||||
(getDynamicClassID() == that.getDynamicClassID() &&
|
||||
StringEnumeration::operator==(that) &&
|
||||
equals(that)));
|
||||
}
|
||||
private:
|
||||
UBool equals(const StringEnumeration& other) const{
|
||||
if (other.getDynamicClassID() != TimeZoneKeysEnumeration::getStaticClassID()) {
|
||||
return FALSE;
|
||||
}
|
||||
TimeZoneKeysEnumeration& enum2 = (TimeZoneKeysEnumeration&)(other);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
int32_t count1 = count(status);
|
||||
int32_t count2 = other.count(status);
|
||||
if(count1 != count2){
|
||||
return FALSE;
|
||||
}
|
||||
int32_t pos1 = 0;
|
||||
int32_t pos2 = 0;
|
||||
const UnicodeString* str1 = NULL;
|
||||
const UnicodeString* str2 = NULL;
|
||||
|
||||
while((str1 = snext(pos1, status))!=NULL){
|
||||
str2 = enum2.snext(pos2, status);
|
||||
if(U_FAILURE(status)){
|
||||
return FALSE;
|
||||
}
|
||||
if(*str1 != *str2){
|
||||
// bail out at the first failure
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
// if we reached here that means that the enumerations are equal
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneKeysEnumeration);
|
||||
|
@ -1328,8 +1352,8 @@ DateFormatSymbols::initZoneStringsArray(UErrorCode& status){
|
|||
fZoneStringsRowCount = fZoneIDEnumeration->count(status);
|
||||
fZoneStringsColCount = 8;
|
||||
fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));
|
||||
/* test for NULL */
|
||||
if (fZoneStrings == 0) {
|
||||
/* if we can't get a chunk of heap then the system is going down. Pin the blame on system*/
|
||||
if (fZoneStrings == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
@ -1365,6 +1389,25 @@ DateFormatSymbols::initZoneStringsArray(UErrorCode& status){
|
|||
}
|
||||
}
|
||||
|
||||
UBool U_CALLCONV
|
||||
uhash_compareTZHashValues(const UHashTok val1, const UHashTok val2){
|
||||
|
||||
const UnicodeString* array1 = (UnicodeString*) val1.pointer;
|
||||
const UnicodeString* array2 = (UnicodeString*) val2.pointer;
|
||||
if(array1==array2){
|
||||
return TRUE;
|
||||
}
|
||||
if(array1==NULL || array2==NULL){
|
||||
return FALSE;
|
||||
}
|
||||
for(int32_t j=0; j< UTZ_MAX_DISPLAY_STRINGS_LENGTH; j++){
|
||||
if(array1[j] != array2[j]){
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
DateFormatSymbols::initZoneStrings(UErrorCode &status){
|
||||
if(U_FAILURE(status)){
|
||||
|
@ -1376,7 +1419,7 @@ DateFormatSymbols::initZoneStrings(UErrorCode &status){
|
|||
}
|
||||
int32_t i;
|
||||
|
||||
fZoneStringsHash = new Hashtable(status);
|
||||
fZoneStringsHash = new Hashtable(uhash_compareUnicodeString, uhash_compareTZHashValues, status);
|
||||
if(fZoneStringsHash==NULL){
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
|
@ -1495,12 +1538,7 @@ DateFormatSymbols::initZoneStrings(UErrorCode &status){
|
|||
}
|
||||
}
|
||||
void
|
||||
DateFormatSymbols::initZoneStrings(const UnicodeString** strings, int32_t rowCount, int32_t columnCount){
|
||||
// This method should have a status parameter
|
||||
// but setZoneStrings API that calls this method does not have one
|
||||
// setZoneStrings API is unsafe and should be deprecated!!
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
DateFormatSymbols::initZoneStrings(const UnicodeString** strings, int32_t rowCount, int32_t columnCount, UErrorCode& status){
|
||||
if(strings==NULL || rowCount<0 || columnCount<0){
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
|
@ -1514,7 +1552,7 @@ DateFormatSymbols::initZoneStrings(const UnicodeString** strings, int32_t rowCou
|
|||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
fZoneStringsHash = new Hashtable(status);
|
||||
fZoneStringsHash = new Hashtable(uhash_compareUnicodeString, uhash_compareTZHashValues, status);
|
||||
if(U_FAILURE(status)){
|
||||
return;
|
||||
}
|
||||
|
@ -1637,7 +1675,7 @@ DateFormatSymbols::setZoneString(const UnicodeString &zid, const TimeZoneTransla
|
|||
Hashtable*
|
||||
DateFormatSymbols::createZoneStringsHash(const Hashtable* otherHash){
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Hashtable* hash = new Hashtable(status);
|
||||
Hashtable* hash = new Hashtable(uhash_compareUnicodeString, uhash_compareTZHashValues, status);
|
||||
if(hash==NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1669,76 +1707,7 @@ DateFormatSymbols::createZoneStringsHash(const Hashtable* otherHash){
|
|||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* compares 2 StringEnumerations
|
||||
*/
|
||||
UBool
|
||||
DateFormatSymbols::stringEnumCompare(StringEnumeration* e1,
|
||||
StringEnumeration* e2){
|
||||
TimeZoneKeysEnumeration *enum1 = (TimeZoneKeysEnumeration*)e1;
|
||||
TimeZoneKeysEnumeration *enum2 = (TimeZoneKeysEnumeration*)e2;
|
||||
if(enum1==NULL || enum2==NULL){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
int32_t count1 = enum1->count(status);
|
||||
int32_t count2 = enum2->count(status);
|
||||
if(count1 != count2){
|
||||
return FALSE;
|
||||
}
|
||||
int32_t pos1 = 0;
|
||||
int32_t pos2 = 0;
|
||||
const UnicodeString* str1 = NULL;
|
||||
const UnicodeString* str2 = NULL;
|
||||
|
||||
while((str1 = enum1->snext(pos1, status))!=NULL){
|
||||
str2 = enum2->snext(pos2, status);
|
||||
if(U_FAILURE(status)){
|
||||
return FALSE;
|
||||
}
|
||||
if(*str1 != *str2){
|
||||
// bail out at the first failure
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
// if we reached here that means that the enumerations are equal
|
||||
return TRUE;
|
||||
}
|
||||
/**
|
||||
* compares 2 Hashtables
|
||||
*/
|
||||
UBool
|
||||
DateFormatSymbols::hashCompare(Hashtable* hash1,
|
||||
Hashtable* hash2){
|
||||
|
||||
if(hash1==NULL || hash2==NULL){
|
||||
return FALSE;
|
||||
}
|
||||
int32_t count1 = hash1->count();
|
||||
int32_t count2 = hash2->count();
|
||||
if(count1!=count2){
|
||||
return FALSE;
|
||||
}
|
||||
int32_t pos1=-1;
|
||||
for(int32_t i=0; i<count1; i++){
|
||||
const UHashElement* elem1 = hash1->nextElement(pos1);
|
||||
UnicodeString* key1 = (UnicodeString*) elem1->key.pointer;
|
||||
UnicodeString* array1 = (UnicodeString*) elem1->value.pointer;
|
||||
UnicodeString* array2 = (UnicodeString*)hash2->get(*key1);
|
||||
if(array1==NULL || array2==NULL){
|
||||
return FALSE;
|
||||
}
|
||||
for(int32_t j=0; j< UTZ_MAX_DISPLAY_STRINGS_LENGTH; j++){
|
||||
if(array1[j] != array2[j]){
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
UnicodeString&
|
||||
DateFormatSymbols::getZoneID(const UnicodeString& zid, UnicodeString& result, UErrorCode& status){
|
||||
if(fZoneStringsHash == NULL){
|
||||
|
|
|
@ -478,13 +478,7 @@ OlsonTimeZone::getDSTSavings() const{
|
|||
if(finalZone!=NULL){
|
||||
return finalZone->getDSTSavings();
|
||||
}
|
||||
// return super->getDSTSavings();
|
||||
// this is basically identical to implementation in
|
||||
// superclass timezone
|
||||
if (useDaylightTime()) {
|
||||
return 3600000;
|
||||
}
|
||||
return 0;
|
||||
return TimeZone::getDSTSavings();
|
||||
}
|
||||
/**
|
||||
* TimeZone API.
|
||||
|
|
|
@ -384,15 +384,6 @@ SimpleDateFormat::initialize(const Locale& locale,
|
|||
{
|
||||
if (U_FAILURE(status)) return;
|
||||
|
||||
// {sfb} should this be here?
|
||||
/*
|
||||
commenting this code out check for bogus locale data does not belong here
|
||||
if (fSymbols->fZoneStringsColCount < 1)
|
||||
{
|
||||
status = U_INVALID_FORMAT_ERROR; // Check for bogus locale data
|
||||
return;
|
||||
}
|
||||
*/
|
||||
// We don't need to check that the row count is >= 1, since all 2d arrays have at
|
||||
// least one row
|
||||
fNumberFormat = NumberFormat::createInstance(locale, status);
|
||||
|
@ -1557,47 +1548,7 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
|||
return -start;
|
||||
}
|
||||
}
|
||||
/*
|
||||
int32_t
|
||||
SimpleDateFormat::getTimeZoneIndex(const UnicodeString& id) const
|
||||
{
|
||||
int32_t i = fSymbols->fZoneStringsRowCount;
|
||||
while (--i >= 0 && fSymbols->fZoneStrings[i][0] != id);
|
||||
return i;
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleDateFormat::matchZoneString(const UnicodeString& text, int32_t start, int32_t zi) const
|
||||
{
|
||||
// ### TODO markus 20021014: This use of caseCompare() will fail
|
||||
// if the text contains a character that case-folds into multiple
|
||||
// characters. In that case, zs->length() may be too long, and it does not match.
|
||||
// We need a case-insensitive version of startsWith().
|
||||
// There are similar cases of such caseCompare() uses elsewhere in ICU.
|
||||
|
||||
int32_t i = fSymbols->fZoneStringsColCount;
|
||||
const int32_t zscc = i;
|
||||
|
||||
while (--i >= 1) {
|
||||
if (i == 5 && (zscc == 6 || zscc >= 8)) { // skip city name if we have it
|
||||
continue;
|
||||
}
|
||||
|
||||
// Checking long and short zones [1 & 2],
|
||||
// and long and short daylight [3 & 4],
|
||||
// and long and short generic [6 & 7]
|
||||
const UnicodeString& zs = fSymbols->fZoneStrings[zi][i];
|
||||
if (zs.length() > 0 && 0 == text.caseCompare(start, zs.length(), zs, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* find time zone 'text' matched zoneStrings and set cal.
|
||||
* includes optimizations for calendar and default time zones
|
||||
*/
|
||||
int32_t
|
||||
SimpleDateFormat::subParseZoneString(const UnicodeString& text, int32_t start, Calendar& cal, UErrorCode& status) const
|
||||
{
|
||||
|
|
|
@ -151,7 +151,7 @@ uprv_uca_initTempTable(UCATableHeader *image, UColOptionSet *opts, const UCollat
|
|||
UCOL_SPECIAL_FLAG | (initTag<<24),
|
||||
UCOL_SPECIAL_FLAG | (supplementaryInitTag << 24),
|
||||
TRUE); // Do your own mallocs for the structure, array and have linear Latin 1
|
||||
t->prefixLookup = uhash_open(prefixLookupHash, prefixLookupComp, status);
|
||||
t->prefixLookup = uhash_open(prefixLookupHash, prefixLookupComp, NULL, status);
|
||||
uhash_setValueDeleter(t->prefixLookup, uhash_freeBlock);
|
||||
|
||||
t->contractions = uprv_cnttab_open(t->mapping, status);
|
||||
|
|
|
@ -1820,7 +1820,7 @@ void ucol_tok_initTokenList(UColTokenParser *src, const UChar *rules, const uint
|
|||
if(U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
src->tailored = uhash_open(uhash_hashTokens, uhash_compareTokens, status);
|
||||
src->tailored = uhash_open(uhash_hashTokens, uhash_compareTokens, NULL, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -668,7 +668,7 @@ private:
|
|||
* initialzes the zoneStrings has and keys enumeration after reading the strings[][]. Required for backwards
|
||||
* compatibility of setZoneStrings method
|
||||
*/
|
||||
void initZoneStrings(const UnicodeString** strings, int32_t rowCount, int32_t collumnCount);
|
||||
void initZoneStrings(const UnicodeString** strings, int32_t rowCount, int32_t collumnCount, UErrorCode& status);
|
||||
/**
|
||||
* initialization of the fZoneStrings data member
|
||||
*/
|
||||
|
@ -677,15 +677,7 @@ private:
|
|||
* Creates a deep clone of the Hashtable
|
||||
*/
|
||||
Hashtable* createZoneStringsHash(const Hashtable* otherHash);
|
||||
/**
|
||||
* compares 2 StringEnumerations
|
||||
*/
|
||||
static UBool stringEnumCompare(StringEnumeration* enum1, StringEnumeration* enum2);
|
||||
/**
|
||||
* compares 2 Hashtables
|
||||
*/
|
||||
static UBool hashCompare(Hashtable* hash1, Hashtable* hash2);
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the key from the hashtable for a given ID.
|
||||
* e.g: for a given ID such as PST returns "Americal/Los_Angeles"
|
||||
|
|
|
@ -772,12 +772,6 @@ private:
|
|||
*/
|
||||
void parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Given a canonical time zone id, return the row index in our symbols for that id,
|
||||
* or -1 if none found.
|
||||
*
|
||||
int32_t getTimeZoneIndex(const UnicodeString& id) const;
|
||||
*/
|
||||
/**
|
||||
* Given text, a start in the text, and a row index, return the column index that
|
||||
* of the zone name that matches (case insensitive) at start, or 0 if none matches.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2000-2004, International Business Machines
|
||||
* Copyright (C) 2000-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
* Date Name Description
|
||||
|
@ -103,7 +103,7 @@ static void TestBasic(void) {
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UHashtable *hash;
|
||||
|
||||
hash = uhash_open(hashChars, isEqualChars, &status);
|
||||
hash = uhash_open(hashChars, isEqualChars, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
|
||||
u_errorName(status), hash);
|
||||
|
@ -163,7 +163,7 @@ static void TestOtherAPI(void){
|
|||
static const UChar five[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
|
||||
static const UChar five2[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
|
||||
|
||||
hash = uhash_open(uhash_hashUChars, uhash_compareUChars, &status);
|
||||
hash = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
|
||||
u_errorName(status), hash);
|
||||
|
@ -287,7 +287,7 @@ static void hashIChars(void) {
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UHashtable *hash;
|
||||
|
||||
hash = uhash_open(uhash_hashIChars, uhash_compareIChars, &status);
|
||||
hash = uhash_open(uhash_hashIChars, uhash_compareIChars, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
|
||||
u_errorName(status), hash);
|
||||
|
|
|
@ -1515,6 +1515,11 @@ void DateFormatTest::TestTimeZoneStringsAPI() {
|
|||
errln("Could not create the StringEnumeration for Locale::getUS(). Error: %s", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
StringEnumeration* keys2 = symbols.createZoneStringIDs(status);
|
||||
if(*keys2!=*keys){
|
||||
errln("operator!= failed for TimeZoneStringsEnum");
|
||||
}
|
||||
const UnicodeString* key = NULL;
|
||||
|
||||
while( (key = keys->snext(status))!=NULL){
|
||||
|
|
|
@ -305,8 +305,11 @@ void IntlTestDateFormatSymbols::TestSymbols(/* char *par */)
|
|||
|
||||
en = fr;
|
||||
|
||||
if(en != fr || foo != bar) {
|
||||
errln("ERROR: Copy Constructor or Assignment failed");
|
||||
if(en != fr) {
|
||||
errln("ERROR: Assignment operator failed");
|
||||
}
|
||||
if(foo != bar) {
|
||||
errln("ERROR: Copy Constructor failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ storeMapping(uint32_t codepoint, uint32_t* mapping,int32_t length,
|
|||
|
||||
/* initialize the hashtable */
|
||||
if(hashTable==NULL){
|
||||
hashTable = uhash_open(hashEntry, compareEntries, status);
|
||||
hashTable = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
uhash_setValueDeleter(hashTable, valueDeleter);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue