From 81fc8fb03e5c955e7a7349e2a347c4a412123ecf Mon Sep 17 00:00:00 2001 From: George Rhoten Date: Fri, 31 Aug 2001 02:21:34 +0000 Subject: [PATCH] ICU-770 More data cleanup X-SVN-Rev: 5652 --- icu4c/source/i18n/timezone.cpp | 72 +++++++++++++++++++++------ icu4c/source/i18n/unicode/timezone.h | 6 +-- icu4c/source/test/cintltst/cmsgtst.c | 4 +- icu4c/source/test/cintltst/nucnvtst.c | 12 ++--- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/icu4c/source/i18n/timezone.cpp b/icu4c/source/i18n/timezone.cpp index b08f20138f2..315f0edae77 100644 --- a/icu4c/source/i18n/timezone.cpp +++ b/icu4c/source/i18n/timezone.cpp @@ -42,11 +42,12 @@ #include "unicode/udata.h" #include "tzdat.h" #include "cstring.h" +#include "ucln_in.h" // static initialization char TimeZone::fgClassID = 0; // Value is irrelevant -TimeZone* TimeZone::fgDefaultZone = NULL; +TimeZone* DEFAULT_ZONE = NULL; static const UChar GMT_ID[] = {0x47, 0x4D, 0x54, 0x00}; /* "GMT" */ static const int32_t GMT_ID_LENGTH = 3; @@ -60,14 +61,16 @@ const TimeZone* TimeZone::GMT = getGMT(); #endif // See header file for documentation of the following -static const TZHeader * DATA = 0; +static const TZHeader * DATA = NULL; static const uint32_t* INDEX_BY_ID = 0; static const OffsetIndex* INDEX_BY_OFFSET = 0; static const CountryIndex* INDEX_BY_COUNTRY = 0; static UnicodeString* ZONE_IDS = 0; -static UBool DATA_LOADED = FALSE; static UDataMemory* UDATA_POINTER = 0; static UMTX LOCK; +static UBool DATA_LOADED = FALSE; + +const TimeZone* GMT = NULL; static void loadZoneData(void); static const TZEquivalencyGroup* lookupEquivalencyGroup(const UnicodeString& id); @@ -77,8 +80,10 @@ static const TZEquivalencyGroup* lookupEquivalencyGroup(const UnicodeString& id) const TimeZone* TimeZone::getGMT(void) { - static const SimpleTimeZone SIMPLE_GMT(0, UnicodeString(GMT_ID, GMT_ID_LENGTH)); - return &SIMPLE_GMT; + if (!DATA_LOADED) { + loadZoneData(); + } + return GMT; } /** @@ -101,6 +106,36 @@ isTimeZoneDataAcceptable(void * /*context*/, } U_CDECL_END +UBool timeZone_cleanup() +{ + DATA = NULL; + INDEX_BY_ID = NULL; + INDEX_BY_OFFSET = NULL; + INDEX_BY_COUNTRY = NULL; + if (ZONE_IDS) { + delete []ZONE_IDS; + ZONE_IDS = NULL; + } + if (UDATA_POINTER) { + udata_close(UDATA_POINTER); + UDATA_POINTER = NULL; + } + if (LOCK) { + umtx_destroy(&LOCK); + LOCK = NULL; + } + if (::GMT) { + delete ::GMT; + ::GMT = NULL; + } + if (DEFAULT_ZONE) { + delete DEFAULT_ZONE; + DEFAULT_ZONE = NULL; + } + DATA_LOADED = FALSE; + return TRUE; +} + /** * Attempt to load the system zone data from icudata.dll (or its * equivalent). After this call returns DATA_LOADED will be true. @@ -116,7 +151,9 @@ U_CDECL_END */ static void loadZoneData() { if (!DATA_LOADED) { + umtx_lock(NULL); Mutex lock(&LOCK); + umtx_unlock(NULL); if (!DATA_LOADED) { UErrorCode status = U_ZERO_ERROR; UDATA_POINTER = udata_openChoice(0, TZ_DATA_TYPE, TZ_DATA_NAME, // THIS IS NOT A LEAK! @@ -156,6 +193,8 @@ static void loadZoneData() { // Whether we succeed or fail, stop future attempts DATA_LOADED = TRUE; + ::GMT = new SimpleTimeZone(0, UnicodeString(GMT_ID, GMT_ID_LENGTH)); + ucln_i18n_registerCleanup(); } } } @@ -292,9 +331,9 @@ TimeZone::initDefault() // fgDefaultZone from the system default time zone. If // fgDefaultZone is already filled in, we obviously don't have to // do anything. - if (fgDefaultZone == 0) { + if (DEFAULT_ZONE == 0) { Mutex lock(&LOCK); - if (fgDefaultZone == 0) { + if (DEFAULT_ZONE == 0) { // We access system timezone data through TPlatformUtilities, // including tzset(), timezone, and tzname[]. int32_t rawOffset = 0; @@ -322,7 +361,7 @@ TimeZone::initDefault() // but that means we'd have to do so for every locale. A // better way is to use the offset and find a // corresponding zone, which is what we do below. - fgDefaultZone = createSystemTimeZone(hostID); + DEFAULT_ZONE = createSystemTimeZone(hostID); // If we couldn't get the time zone ID from the host, use // the default host timezone offset. Further refinements @@ -330,7 +369,7 @@ TimeZone::initDefault() // is in use or not and possibly using the host locale to // select from multiple zones at a the same offset. We // don't do any of this now, but we could easily add this. - if (fgDefaultZone == 0 && DATA != 0) { + if (DEFAULT_ZONE == 0 && DATA != 0) { // Use the designated default in the time zone list that has the // appropriate GMT offset, if there is one. @@ -343,7 +382,7 @@ TimeZone::initDefault() } if (index->gmtOffset == rawOffset) { // Found our desired offset - fgDefaultZone = createTimeZone(ZONE_IDS[index->defaultZone]); + DEFAULT_ZONE = createTimeZone(ZONE_IDS[index->defaultZone]); break; } // Compute the position of the next entry. If the delta value @@ -359,9 +398,10 @@ TimeZone::initDefault() // If we _still_ don't have a time zone, use GMT. This // can only happen if the raw offset returned by // uprv_timezone() does not correspond to any system zone. - if (fgDefaultZone == 0) { - fgDefaultZone = getGMT()->clone(); + if (DEFAULT_ZONE == 0) { + DEFAULT_ZONE = getGMT()->clone(); } + ucln_i18n_registerCleanup(); } } } @@ -373,7 +413,7 @@ TimeZone::createDefault() { initDefault(); // After this call fgDefaultZone is not NULL Mutex lock(&LOCK); // In case adoptDefault is called - return fgDefaultZone->clone(); + return DEFAULT_ZONE->clone(); } // ------------------------------------- @@ -385,11 +425,11 @@ TimeZone::adoptDefault(TimeZone* zone) { Mutex mutex(&LOCK); - if (fgDefaultZone != NULL) { - delete fgDefaultZone; + if (DEFAULT_ZONE != NULL) { + delete DEFAULT_ZONE; } - fgDefaultZone = zone; + DEFAULT_ZONE = zone; } } // ------------------------------------- diff --git a/icu4c/source/i18n/unicode/timezone.h b/icu4c/source/i18n/unicode/timezone.h index 94ff77e2f3e..237621cb759 100644 --- a/icu4c/source/i18n/unicode/timezone.h +++ b/icu4c/source/i18n/unicode/timezone.h @@ -533,19 +533,17 @@ protected: private: static char fgClassID; - static TimeZone* fgDefaultZone; // default time zone (lazy evaluated) - static TimeZone* createCustomTimeZone(const UnicodeString&); // Creates a time zone based on the string. /** - * Responsible for setting up fgDefaultZone. Uses routines in TPlatformUtilities + * Responsible for setting up DEFAULT_ZONE. Uses routines in TPlatformUtilities * (i.e., platform-specific calls) to get the current system time zone. Failing * that, uses the platform-specific default time zone. Failing that, uses GMT. */ static void initDefault(void); // See source file for documentation - static TimeZone* createSystemTimeZone(const UnicodeString& name); + static TimeZone* createSystemTimeZone(const UnicodeString& name); UnicodeString fID; // this time zone's ID }; diff --git a/icu4c/source/test/cintltst/cmsgtst.c b/icu4c/source/test/cintltst/cmsgtst.c index 4e19dc2a2b3..615cc56468f 100644 --- a/icu4c/source/test/cintltst/cmsgtst.c +++ b/icu4c/source/test/cintltst/cmsgtst.c @@ -656,7 +656,9 @@ static void OpenMessageFormatTest(void) } /* umsg_format umsg_parse */ - + umsg_close(f1); + umsg_close(f2); + umsg_close(f3); } void addMsgForTest(TestNode** root); diff --git a/icu4c/source/test/cintltst/nucnvtst.c b/icu4c/source/test/cintltst/nucnvtst.c index 9f291bec7cc..4ad45cdd881 100644 --- a/icu4c/source/test/cintltst/nucnvtst.c +++ b/icu4c/source/test/cintltst/nucnvtst.c @@ -4046,7 +4046,7 @@ TestLMBCS() { errorCode = U_ZERO_ERROR; pUOut = UOut; - ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut),(const char **)&pLIn,(const char *)(pLIn+5),off,TRUE, &errorCode); + ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut)/sizeof(UChar),(const char **)&pLIn,(const char *)(pLIn+5),off,TRUE, &errorCode); if (UOut[0] != 0xD801 || errorCode != U_TRUNCATED_CHAR_FOUND || pUOut != UOut + 1 || pLIn != LIn + 5) { log_err("Unexpected results on chopped low surrogate\n"); @@ -4060,7 +4060,7 @@ TestLMBCS() { errorCode = U_ZERO_ERROR; pUOut = UOut; - ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut),(const char **)&pLIn,(const char *)(pLIn+3),off,TRUE, &errorCode); + ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut)/sizeof(UChar),(const char **)&pLIn,(const char *)(pLIn+3),off,TRUE, &errorCode); if (UOut[0] != 0xD801 || U_FAILURE(errorCode) || pUOut != UOut + 1 || pLIn != LIn + 3) { log_err("Unexpected results on chopped at surrogate boundary \n"); @@ -4077,7 +4077,7 @@ TestLMBCS() { errorCode = U_ZERO_ERROR; pUOut = UOut; - ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut),(const char **)&pLIn,(const char *)(pLIn+6),off,TRUE, &errorCode); + ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut)/sizeof(UChar),(const char **)&pLIn,(const char *)(pLIn+6),off,TRUE, &errorCode); if (UOut[0] != 0xD801 || UOut[1] != 0xC9D0 || U_FAILURE(errorCode) || pUOut != UOut + 2 || pLIn != LIn + 6) { log_err("Unexpected results after unpaired surrogate plus valid Unichar \n"); @@ -4094,7 +4094,7 @@ TestLMBCS() { errorCode = U_ZERO_ERROR; pUOut = UOut; - ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut),(const char **)&pLIn,(const char *)(pLIn+5),off,TRUE, &errorCode); + ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut)/sizeof(UChar),(const char **)&pLIn,(const char *)(pLIn+5),off,TRUE, &errorCode); if (UOut[0] != 0xD801 || errorCode != U_TRUNCATED_CHAR_FOUND || pUOut != UOut + 1 || pLIn != LIn + 5) { log_err("Unexpected results after unpaired surrogate plus chopped Unichar \n"); @@ -4111,7 +4111,7 @@ TestLMBCS() { errorCode = U_ZERO_ERROR; pUOut = UOut; - ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut),(const char **)&pLIn,(const char *)(pLIn+5),off,TRUE, &errorCode); + ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut)/sizeof(UChar),(const char **)&pLIn,(const char *)(pLIn+5),off,TRUE, &errorCode); if (UOut[0] != 0xD801 || UOut[1] != 0x1B || U_FAILURE(errorCode) || pUOut != UOut + 2 || pLIn != LIn + 5) { log_err("Unexpected results after unpaired surrogate plus valid non-Unichar\n"); @@ -4127,7 +4127,7 @@ TestLMBCS() { errorCode = U_ZERO_ERROR; pUOut = UOut; - ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut),(const char **)&pLIn,(const char *)(pLIn+4),off,TRUE, &errorCode); + ucnv_toUnicode(cnv, &pUOut,pUOut+sizeof(UOut)/sizeof(UChar),(const char **)&pLIn,(const char *)(pLIn+4),off,TRUE, &errorCode); if (UOut[0] != 0xD801 || errorCode != U_TRUNCATED_CHAR_FOUND || pUOut != UOut + 1 || pLIn != LIn + 4) {