]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/zonemeta.cpp
ICU-64260.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / zonemeta.cpp
index be71a3b4fd9e38c7999a5fe8184de158723f2e80..cc53ef9a12a69da1d1abfd40f037e4a8182f67e4 100644 (file)
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 2007-2014, International Business Machines Corporation and
 /*
 *******************************************************************************
 * Copyright (C) 2007-2014, International Business Machines Corporation and
@@ -15,7 +17,7 @@
 #include "unicode/ustring.h"
 #include "unicode/putil.h"
 #include "unicode/simpletz.h"
 #include "unicode/ustring.h"
 #include "unicode/putil.h"
 #include "unicode/simpletz.h"
-
+#include "unicode/strenum.h"
 #include "umutex.h"
 #include "uvector.h"
 #include "cmemory.h"
 #include "umutex.h"
 #include "uvector.h"
 #include "cmemory.h"
 #include "uresimp.h"
 #include "uhash.h"
 #include "olsontz.h"
 #include "uresimp.h"
 #include "uhash.h"
 #include "olsontz.h"
+#include "uinvchar.h"
 
 
-#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
-
-static UMutex gZoneMetaLock = U_MUTEX_INITIALIZER;
+static icu::UMutex *gZoneMetaLock() {
+    static icu::UMutex *m = STATIC_NEW(icu::UMutex);
+    return m;
+}
 
 // CLDR Canonical ID mapping table
 static UHashtable *gCanonicalIDCache = NULL;
 
 // CLDR Canonical ID mapping table
 static UHashtable *gCanonicalIDCache = NULL;
@@ -255,12 +259,18 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
     tzid.extract(utzid, ZID_KEY_MAX + 1, tmpStatus);
     U_ASSERT(tmpStatus == U_ZERO_ERROR);    // we checked the length of tzid already
 
     tzid.extract(utzid, ZID_KEY_MAX + 1, tmpStatus);
     U_ASSERT(tmpStatus == U_ZERO_ERROR);    // we checked the length of tzid already
 
+    if (!uprv_isInvariantUString(utzid, -1)) {
+        // All of known tz IDs are only containing ASCII invariant characters.
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+
     // Check if it was already cached
     // Check if it was already cached
-    umtx_lock(&gZoneMetaLock);
+    umtx_lock(gZoneMetaLock());
     {
         canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
     }
     {
         canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
     }
-    umtx_unlock(&gZoneMetaLock);
+    umtx_unlock(gZoneMetaLock());
 
     if (canonicalID != NULL) {
         return canonicalID;
 
     if (canonicalID != NULL) {
         return canonicalID;
@@ -269,7 +279,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
     // If not, resolve CLDR canonical ID with resource data
     UBool isInputCanonical = FALSE;
     char id[ZID_KEY_MAX + 1];
     // If not, resolve CLDR canonical ID with resource data
     UBool isInputCanonical = FALSE;
     char id[ZID_KEY_MAX + 1];
-    tzid.extract(0, 0x7fffffff, id, LENGTHOF(id), US_INV);
+    tzid.extract(0, 0x7fffffff, id, UPRV_LENGTHOF(id), US_INV);
 
     // replace '/' with ':'
     char *p = id;
 
     // replace '/' with ':'
     char *p = id;
@@ -312,10 +322,10 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
                 id[len] = (char) 0; // Make sure it is null terminated.
 
                 // replace '/' with ':'
                 id[len] = (char) 0; // Make sure it is null terminated.
 
                 // replace '/' with ':'
-                char *p = id;
-                while (*p++) {
-                    if (*p == '/') {
-                        *p = ':';
+                char *q = id;
+                while (*q++) {
+                    if (*q == '/') {
+                        *q = ':';
                     }
                 }
 
                     }
                 }
 
@@ -341,7 +351,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
         U_ASSERT(canonicalID != NULL);  // canocanilD must be non-NULL here
 
         // Put the resolved canonical ID to the cache
         U_ASSERT(canonicalID != NULL);  // canocanilD must be non-NULL here
 
         // Put the resolved canonical ID to the cache
-        umtx_lock(&gZoneMetaLock);
+        umtx_lock(gZoneMetaLock());
         {
             const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
             if (idInCache == NULL) {
         {
             const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
             if (idInCache == NULL) {
@@ -361,7 +371,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
                 }
             }
         }
                 }
             }
         }
-        umtx_unlock(&gZoneMetaLock);
+        umtx_unlock(gZoneMetaLock());
     }
 
     return canonicalID;
     }
 
     return canonicalID;
@@ -439,14 +449,14 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
         // Check if it was already cached
         UBool cached = FALSE;
         UBool singleZone = FALSE;
         // Check if it was already cached
         UBool cached = FALSE;
         UBool singleZone = FALSE;
-        umtx_lock(&gZoneMetaLock);
+        umtx_lock(gZoneMetaLock());
         {
             singleZone = cached = gSingleZoneCountries->contains((void*)region);
             if (!cached) {
                 cached = gMultiZonesCountries->contains((void*)region);
             }
         }
         {
             singleZone = cached = gSingleZoneCountries->contains((void*)region);
             if (!cached) {
                 cached = gMultiZonesCountries->contains((void*)region);
             }
         }
-        umtx_unlock(&gZoneMetaLock);
+        umtx_unlock(gZoneMetaLock());
 
         if (!cached) {
             // We need to go through all zones associated with the region.
 
         if (!cached) {
             // We need to go through all zones associated with the region.
@@ -465,7 +475,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
             delete ids;
 
             // Cache the result
             delete ids;
 
             // Cache the result
-            umtx_lock(&gZoneMetaLock);
+            umtx_lock(gZoneMetaLock());
             {
                 UErrorCode ec = U_ZERO_ERROR;
                 if (singleZone) {
             {
                 UErrorCode ec = U_ZERO_ERROR;
                 if (singleZone) {
@@ -478,7 +488,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
                     }
                 }
             }
                     }
                 }
             }
-            umtx_unlock(&gZoneMetaLock);
+            umtx_unlock(gZoneMetaLock());
         }
 
         if (singleZone) {
         }
 
         if (singleZone) {
@@ -565,11 +575,11 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
     // get the mapping from cache
     const UVector *result = NULL;
 
     // get the mapping from cache
     const UVector *result = NULL;
 
-    umtx_lock(&gZoneMetaLock);
+    umtx_lock(gZoneMetaLock());
     {
         result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
     }
     {
         result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
     }
-    umtx_unlock(&gZoneMetaLock);
+    umtx_unlock(gZoneMetaLock());
 
     if (result != NULL) {
         return result;
 
     if (result != NULL) {
         return result;
@@ -583,7 +593,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
     }
 
     // put the new one into the cache
     }
 
     // put the new one into the cache
-    umtx_lock(&gZoneMetaLock);
+    umtx_lock(gZoneMetaLock());
     {
         // make sure it's already created
         result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
     {
         // make sure it's already created
         result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
@@ -611,7 +621,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
             delete tmpResult;
         }
     }
             delete tmpResult;
         }
     }
-    umtx_unlock(&gZoneMetaLock);
+    umtx_unlock(gZoneMetaLock());
 
     return result;
 }
 
     return result;
 }
@@ -683,7 +693,7 @@ ZoneMeta::createMetazoneMappings(const UnicodeString &tzid) {
                     mzMappings = new UVector(deleteOlsonToMetaMappingEntry, NULL, status);
                     if (U_FAILURE(status)) {
                         delete mzMappings;
                     mzMappings = new UVector(deleteOlsonToMetaMappingEntry, NULL, status);
                     if (U_FAILURE(status)) {
                         delete mzMappings;
-                        deleteOlsonToMetaMappingEntry(entry);
+                        mzMappings = NULL;
                         uprv_free(entry);
                         break;
                     }
                         uprv_free(entry);
                         break;
                     }
@@ -777,15 +787,14 @@ static void U_CALLCONV initAvailableMetaZoneIDs () {
 
     UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status);
     UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status);
 
     UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status);
     UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status);
-    UResourceBundle res;
-    ures_initStackObject(&res);
+    StackUResourceBundle res;
     while (U_SUCCESS(status) && ures_hasNext(bundle)) {
     while (U_SUCCESS(status) && ures_hasNext(bundle)) {
-        ures_getNextResource(bundle, &res, &status);
+        ures_getNextResource(bundle, res.getAlias(), &status);
         if (U_FAILURE(status)) {
             break;
         }
         if (U_FAILURE(status)) {
             break;
         }
-        const char *mzID = ures_getKey(&res);
-        int32_t len = uprv_strlen(mzID);
+        const char *mzID = ures_getKey(res.getAlias());
+        int32_t len = static_cast<int32_t>(uprv_strlen(mzID));
         UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1));
         if (uMzID == NULL) {
             status = U_MEMORY_ALLOCATION_ERROR;
         UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1));
         if (uMzID == NULL) {
             status = U_MEMORY_ALLOCATION_ERROR;
@@ -802,7 +811,6 @@ static void U_CALLCONV initAvailableMetaZoneIDs () {
             delete usMzID;
         }
     }
             delete usMzID;
         }
     }
-    ures_close(&res);
     ures_close(bundle);
     ures_close(rb);
 
     ures_close(bundle);
     ures_close(rb);
 
@@ -843,13 +851,13 @@ ZoneMeta::createCustomTimeZone(int32_t offset) {
         negative = TRUE;
         tmp = -offset;
     }
         negative = TRUE;
         tmp = -offset;
     }
-    int32_t hour, min, sec;
+    uint8_t hour, min, sec;
 
     tmp /= 1000;
 
     tmp /= 1000;
-    sec = tmp % 60;
+    sec = static_cast<uint8_t>(tmp % 60);
     tmp /= 60;
     tmp /= 60;
-    min = tmp % 60;
-    hour = tmp / 60;
+    min = static_cast<uint8_t>(tmp % 60);
+    hour = static_cast<uint8_t>(tmp / 60);
 
     UnicodeString zid;
     formatCustomID(hour, min, sec, negative, zid);
 
     UnicodeString zid;
     formatCustomID(hour, min, sec, negative, zid);