+// © 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
#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 "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;
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
- umtx_lock(&gZoneMetaLock);
+ umtx_lock(gZoneMetaLock());
{
canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
}
- umtx_unlock(&gZoneMetaLock);
+ umtx_unlock(gZoneMetaLock());
if (canonicalID != NULL) {
return canonicalID;
// 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;
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 = ':';
}
}
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) {
}
}
}
- umtx_unlock(&gZoneMetaLock);
+ umtx_unlock(gZoneMetaLock());
}
return canonicalID;
// 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);
}
}
- umtx_unlock(&gZoneMetaLock);
+ umtx_unlock(gZoneMetaLock());
if (!cached) {
// We need to go through all zones associated with the region.
delete ids;
// Cache the result
- umtx_lock(&gZoneMetaLock);
+ umtx_lock(gZoneMetaLock());
{
UErrorCode ec = U_ZERO_ERROR;
if (singleZone) {
}
}
}
- umtx_unlock(&gZoneMetaLock);
+ umtx_unlock(gZoneMetaLock());
}
if (singleZone) {
// get the mapping from cache
const UVector *result = NULL;
- umtx_lock(&gZoneMetaLock);
+ umtx_lock(gZoneMetaLock());
{
result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
}
- umtx_unlock(&gZoneMetaLock);
+ umtx_unlock(gZoneMetaLock());
if (result != NULL) {
return result;
}
// 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);
delete tmpResult;
}
}
- umtx_unlock(&gZoneMetaLock);
+ umtx_unlock(gZoneMetaLock());
return result;
}
mzMappings = new UVector(deleteOlsonToMetaMappingEntry, NULL, status);
if (U_FAILURE(status)) {
delete mzMappings;
- deleteOlsonToMetaMappingEntry(entry);
+ mzMappings = NULL;
uprv_free(entry);
break;
}
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)) {
- ures_getNextResource(bundle, &res, &status);
+ ures_getNextResource(bundle, res.getAlias(), &status);
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;
delete usMzID;
}
}
- ures_close(&res);
ures_close(bundle);
ures_close(rb);
negative = TRUE;
tmp = -offset;
}
- int32_t hour, min, sec;
+ uint8_t hour, min, sec;
tmp /= 1000;
- sec = tmp % 60;
+ sec = static_cast<uint8_t>(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);