16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2007-2013, International Business Machines Corporation and 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "zonemeta.h" 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/timezone.h" 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/putil.h" 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/simpletz.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "umutex.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uvector.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "gregoimp.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_in.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresimp.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uhash.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "olsontz.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex gZoneMetaLock = U_MUTEX_INITIALIZER; 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// CLDR Canonical ID mapping table 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UHashtable *gCanonicalIDCache = NULL; 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce gCanonicalIDCacheInitOnce = U_INITONCE_INITIALIZER; 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Metazone mapping table 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UHashtable *gOlsonToMeta = NULL; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce gOlsonToMetaInitOnce = U_INITONCE_INITIALIZER; 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Available metazone IDs vector and table 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UVector *gMetaZoneIDs = NULL; 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UHashtable *gMetaZoneIDTable = NULL; 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce gMetaZoneIDsInitOnce = U_INITONCE_INITIALIZER; 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Country info vectors 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UVector *gSingleZoneCountries = NULL; 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UVector *gMultiZonesCountries = NULL; 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce gCountryInfoVectorsInitOnce = U_INITONCE_INITIALIZER; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Cleanup callback func 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV zoneMeta_cleanup(void) 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gCanonicalIDCache != NULL) { 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(gCanonicalIDCache); 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gCanonicalIDCache = NULL; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gCanonicalIDCacheInitOnce.reset(); 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gOlsonToMeta != NULL) { 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(gOlsonToMeta); 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gOlsonToMeta = NULL; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gOlsonToMetaInitOnce.reset(); 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gMetaZoneIDTable != NULL) { 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(gMetaZoneIDTable); 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDTable = NULL; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // delete after closing gMetaZoneIDTable, because it holds 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // value objects held by the hashtable 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gMetaZoneIDs; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDs = NULL; 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDsInitOnce.reset(); 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gSingleZoneCountries; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gSingleZoneCountries = NULL; 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gMultiZonesCountries; 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMultiZonesCountries = NULL; 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gCountryInfoVectorsInitOnce.reset(); 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Deleter for UChar* string 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteUCharString(void *obj) { 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *entry = (UChar*)obj; 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(entry); 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Deleter for UVector 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteUVector(void *obj) { 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete (icu::UVector*) obj; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Deleter for OlsonToMetaMappingEntry 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteOlsonToMetaMappingEntry(void *obj) { 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org icu::OlsonToMetaMappingEntry *entry = (icu::OlsonToMetaMappingEntry*)obj; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(entry); 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ZID_KEY_MAX 128 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gMetaZones[] = "metaZones"; 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gMetazoneInfo[] = "metazoneInfo"; 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gMapTimezonesTag[] = "mapTimezones"; 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gKeyTypeData[] = "keyTypeData"; 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gTypeAliasTag[] = "typeAlias"; 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gTypeMapTag[] = "typeMap"; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gTimezoneTag[] = "timezone"; 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gPrimaryZonesTag[] = "primaryZones"; 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gWorldTag[] = "001"; 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gWorld[] = {0x30, 0x30, 0x31, 0x00}; // "001" 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gDefaultFrom[] = {0x31, 0x39, 0x37, 0x30, 0x2D, 0x30, 0x31, 0x2D, 0x30, 0x31, 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x20, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00}; // "1970-01-01 00:00" 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gDefaultTo[] = {0x39, 0x39, 0x39, 0x39, 0x2D, 0x31, 0x32, 0x2D, 0x33, 0x31, 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x20, 0x32, 0x33, 0x3A, 0x35, 0x39, 0x00}; // "9999-12-31 23:59" 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gCustomTzPrefix[] = {0x47, 0x4D, 0x54, 0}; // "GMT" 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ASCII_DIGIT(c) (((c)>=0x30 && (c)<=0x39) ? (c)-0x30 : -1) 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Convert a date string used by metazone mappings to UDate. 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The format used by CLDR metazone mapping is "yyyy-MM-dd HH:mm". 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UDate 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgparseDate (const UChar *text, UErrorCode &status) { 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = u_strlen(text); 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len != 16 && len != 10) { 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // It must be yyyy-MM-dd HH:mm (length 16) or yyyy-MM-dd (length 10) 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_FORMAT_ERROR; 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t year = 0, month = 0, day = 0, hour = 0, min = 0, n; 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idx; 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "yyyy" (0 - 3) 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 0; idx <= 3 && U_SUCCESS(status); idx++) { 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org n = ASCII_DIGIT((int32_t)text[idx]); 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = 10*year + n; 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_FORMAT_ERROR; 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "MM" (5 - 6) 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 5; idx <= 6 && U_SUCCESS(status); idx++) { 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org n = ASCII_DIGIT((int32_t)text[idx]); 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = 10*month + n; 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_FORMAT_ERROR; 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "dd" (8 - 9) 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 8; idx <= 9 && U_SUCCESS(status); idx++) { 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org n = ASCII_DIGIT((int32_t)text[idx]); 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org day = 10*day + n; 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_FORMAT_ERROR; 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len == 16) { 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "HH" (11 - 12) 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 11; idx <= 12 && U_SUCCESS(status); idx++) { 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org n = ASCII_DIGIT((int32_t)text[idx]); 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hour = 10*hour + n; 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_FORMAT_ERROR; 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "mm" (14 - 15) 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 14; idx <= 15 && U_SUCCESS(status); idx++) { 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org n = ASCII_DIGIT((int32_t)text[idx]); 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org min = 10*min + n; 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_FORMAT_ERROR; 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate date = Grego::fieldsToDay(year, month - 1, day) * U_MILLIS_PER_DAY 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + hour * U_MILLIS_PER_HOUR + min * U_MILLIS_PER_MINUTE; 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return date; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV initCanonicalIDCache(UErrorCode &status) { 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gCanonicalIDCache = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gCanonicalIDCache == NULL) { 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gCanonicalIDCache = NULL; 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No key/value deleters - keys/values are from a resource bundle 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup); 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* U_EXPORT2 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) { 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = tzid.length(); 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len > ZID_KEY_MAX) { 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Checking the cached results 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gCanonicalIDCacheInitOnce, &initCanonicalIDCache, status); 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *canonicalID = NULL; 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode tmpStatus = U_ZERO_ERROR; 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar utzid[ZID_KEY_MAX + 1]; 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzid.extract(utzid, ZID_KEY_MAX + 1, tmpStatus); 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(tmpStatus == U_ZERO_ERROR); // we checked the length of tzid already 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if it was already cached 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gZoneMetaLock); 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid); 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gZoneMetaLock); 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (canonicalID != NULL) { 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return canonicalID; 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If not, resolve CLDR canonical ID with resource data 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isInputCanonical = FALSE; 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char id[ZID_KEY_MAX + 1]; 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* idChars = tzid.getBuffer(); 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_UCharsToChars(idChars,id,len); 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id[len] = (char) 0; // Make sure it is null terminated. 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // replace '/' with ':' 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *p = id; 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*p++) { 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*p == '/') { 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p = ':'; 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *top = ures_openDirect(NULL, gKeyTypeData, &tmpStatus); 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *rb = ures_getByKey(top, gTypeMapTag, NULL, &tmpStatus); 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus); 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, id, rb, &tmpStatus); 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(tmpStatus)) { 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // type entry (canonical) found 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the input is the canonical ID. resolve to const UChar* 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalID = TimeZone::findID(tzid); 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isInputCanonical = TRUE; 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (canonicalID == NULL) { 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If a map element not found, then look for an alias 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmpStatus = U_ZERO_ERROR; 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(top, gTypeAliasTag, rb, &tmpStatus); 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus); 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *canonical = ures_getStringByKey(rb,id,NULL,&tmpStatus); 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(tmpStatus)) { 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // canonical map found 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalID = canonical; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (canonicalID == NULL) { 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Dereference the input ID using the tz data 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *derefer = TimeZone::dereferOlsonLink(tzid); 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (derefer == NULL) { 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org len = u_strlen(derefer); 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_UCharsToChars(derefer,id,len); 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id[len] = (char) 0; // Make sure it is null terminated. 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // replace '/' with ':' 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *p = id; 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*p++) { 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*p == '/') { 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p = ':'; 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If a dereference turned something up then look for an alias. 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // rb still points to the alias table, so we don't have to go looking 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // for it. 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmpStatus = U_ZERO_ERROR; 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonical = ures_getStringByKey(rb,id,NULL,&tmpStatus); 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(tmpStatus)) { 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // canonical map for the dereferenced ID found 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalID = canonical; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalID = derefer; 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isInputCanonical = TRUE; 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rb); 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(top); 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(canonicalID != NULL); // canocanilD must be non-NULL here 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Put the resolved canonical ID to the cache 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gZoneMetaLock); 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid); 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (idInCache == NULL) { 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* key = ZoneMeta::findTimeZoneID(tzid); 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(key != NULL); 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (key != NULL) { 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org idInCache = (const UChar *)uhash_put(gCanonicalIDCache, (void *)key, (void *)canonicalID, &status); 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(idInCache == NULL); 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && isInputCanonical) { 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Also put canonical ID itself into the cache if not exist 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *canonicalInCache = (const UChar*)uhash_get(gCanonicalIDCache, canonicalID); 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (canonicalInCache == NULL) { 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalInCache = (const UChar *)uhash_put(gCanonicalIDCache, (void *)canonicalID, (void *)canonicalID, &status); 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(canonicalInCache == NULL); 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gZoneMetaLock); 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return canonicalID; 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UnicodeString &systemID, UErrorCode& status) { 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *canonicalID = getCanonicalCLDRID(tzid, status); 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || canonicalID == NULL) { 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org systemID.setToBogus(); 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return systemID; 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org systemID.setTo(TRUE, canonicalID, -1); 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return systemID; 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* U_EXPORT2 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getCanonicalCLDRID(const TimeZone& tz) { 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL) { 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // short cut for OlsonTimeZone 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const OlsonTimeZone *otz = (const OlsonTimeZone*)&tz; 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return otz->getCanonicalID(); 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString tzID; 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return getCanonicalCLDRID(tz.getID(tzID), status); 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV countryInfoVectorsInit(UErrorCode &status) { 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Create empty vectors 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No deleters for these UVectors, it's a reference to a resource bundle string. 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gSingleZoneCountries = new UVector(NULL, uhash_compareUChars, status); 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gSingleZoneCountries == NULL) { 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMultiZonesCountries = new UVector(NULL, uhash_compareUChars, status); 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gMultiZonesCountries == NULL) { 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gSingleZoneCountries; 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gMultiZonesCountries; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gSingleZoneCountries = NULL; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMultiZonesCountries = NULL; 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup); 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country, UBool *isPrimary /* = NULL */) { 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (isPrimary != NULL) { 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *isPrimary = FALSE; 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *region = TimeZone::getRegion(tzid); 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (region != NULL && u_strcmp(gWorld, region) != 0) { 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org country.setTo(region, -1); 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org country.setToBogus(); 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return country; 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (isPrimary != NULL) { 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char regionBuf[] = {0, 0, 0}; 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Checking the cached results 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gCountryInfoVectorsInitOnce, &countryInfoVectorsInit, status); 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return country; 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if it was already cached 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool cached = FALSE; 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool singleZone = FALSE; 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gZoneMetaLock); 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org singleZone = cached = gSingleZoneCountries->contains((void*)region); 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!cached) { 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cached = gMultiZonesCountries->contains((void*)region); 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gZoneMetaLock); 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!cached) { 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We need to go through all zones associated with the region. 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This is relatively heavy operation. 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(u_strlen(region) == 2); 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_UCharsToChars(region, regionBuf, 2); 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org StringEnumeration *ids = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL_LOCATION, regionBuf, NULL, status); 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idsLen = ids->count(status); 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && idsLen == 1) { 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // only the single zone is available for the region 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org singleZone = TRUE; 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete ids; 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Cache the result 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gZoneMetaLock); 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (singleZone) { 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!gSingleZoneCountries->contains((void*)region)) { 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gSingleZoneCountries->addElement((void*)region, ec); 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!gMultiZonesCountries->contains((void*)region)) { 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMultiZonesCountries->addElement((void*)region, ec); 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gZoneMetaLock); 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (singleZone) { 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *isPrimary = TRUE; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Note: We may cache the primary zone map in future. 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Even a country has multiple zones, one of them might be 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // dominant and treated as a primary zone 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idLen = 0; 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (regionBuf[0] == 0) { 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_UCharsToChars(region, regionBuf, 2); 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gPrimaryZonesTag, rb, &status); 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *primaryZone = ures_getStringByKey(rb, regionBuf, &idLen, &status); 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzid.compare(primaryZone, idLen) == 0) { 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *isPrimary = TRUE; 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The given ID might not be a canonical ID 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString canonicalID; 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZone::getCanonicalID(tzid, canonicalID, status); 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && canonicalID.compare(primaryZone, idLen) == 0) { 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *isPrimary = TRUE; 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rb); 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return country; 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getMetazoneID(const UnicodeString &tzid, UDate date, UnicodeString &result) { 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isSet = FALSE; 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UVector *mappings = getMetazoneMappings(tzid); 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mappings != NULL) { 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < mappings->size(); i++) { 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org OlsonToMetaMappingEntry *mzm = (OlsonToMetaMappingEntry*)mappings->elementAt(i); 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzm->from <= date && mzm->to > date) { 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setTo(mzm->mzid, -1); 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isSet = TRUE; 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!isSet) { 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setToBogus(); 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV olsonToMetaInit(UErrorCode &status) { 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(gOlsonToMeta == NULL); 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup); 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gOlsonToMeta = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gOlsonToMeta = NULL; 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setKeyDeleter(gOlsonToMeta, deleteUCharString); 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setValueDeleter(gOlsonToMeta, deleteUVector); 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UVector* U_EXPORT2 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getMetazoneMappings(const UnicodeString &tzid) { 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar tzidUChars[ZID_KEY_MAX + 1]; 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzid.extract(tzidUChars, ZID_KEY_MAX + 1, status); 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) { 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gOlsonToMetaInitOnce, &olsonToMetaInit, status); 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // get the mapping from cache 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UVector *result = NULL; 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gZoneMetaLock); 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars); 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gZoneMetaLock); 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result != NULL) { 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // miss the cache - create new one 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *tmpResult = createMetazoneMappings(tzid); 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tmpResult == NULL) { 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // not available 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // put the new one into the cache 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gZoneMetaLock); 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // make sure it's already created 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars); 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result == NULL) { 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // add the one just created 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tzidLen = tzid.length() + 1; 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *key = (UChar*)uprv_malloc(tzidLen * sizeof(UChar)); 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (key == NULL) { 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // memory allocation error.. just return NULL 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = NULL; 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tmpResult; 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzid.extract(key, tzidLen, status); 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_put(gOlsonToMeta, key, tmpResult, &status); 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // delete the mapping 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = NULL; 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tmpResult; 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = tmpResult; 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // another thread already put the one 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tmpResult; 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gZoneMetaLock); 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUVector* 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::createMetazoneMappings(const UnicodeString &tzid) { 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *mzMappings = NULL; 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString canonicalID; 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gMetazoneInfo, rb, &status); 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org getCanonicalCLDRID(tzid, canonicalID, status); 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char tzKey[ZID_KEY_MAX + 1]; 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tzKeyLen = canonicalID.extract(0, canonicalID.length(), tzKey, sizeof(tzKey), US_INV); 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzKey[tzKeyLen] = 0; 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // tzid keys are using ':' as separators 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *p = tzKey; 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*p) { 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*p == '/') { 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p = ':'; 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p++; 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, tzKey, rb, &status); 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *mz = NULL; 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (ures_hasNext(rb)) { 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mz = ures_getNextResource(rb, mz, &status); 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *mz_name = ures_getStringByIndex(mz, 0, NULL, &status); 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *mz_from = gDefaultFrom; 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *mz_to = gDefaultTo; 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ures_getSize(mz) == 3) { 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mz_from = ures_getStringByIndex(mz, 1, NULL, &status); 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mz_to = ures_getStringByIndex(mz, 2, NULL, &status); 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(status)){ 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We do not want to use SimpleDateformat to parse boundary dates, 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // because this code could be triggered by the initialization code 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // used by SimpleDateFormat. 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate from = parseDate(mz_from, status); 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate to = parseDate(mz_to, status); 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org OlsonToMetaMappingEntry *entry = (OlsonToMetaMappingEntry*)uprv_malloc(sizeof(OlsonToMetaMappingEntry)); 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (entry == NULL) { 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org entry->mzid = mz_name; 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org entry->from = from; 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org entry->to = to; 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzMappings == NULL) { 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mzMappings = new UVector(deleteOlsonToMetaMappingEntry, NULL, status); 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete mzMappings; 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org deleteOlsonToMetaMappingEntry(entry); 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(entry); 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mzMappings->addElement(entry, status); 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(mz); 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzMappings != NULL) { 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete mzMappings; 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mzMappings = NULL; 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rb); 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mzMappings; 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getZoneIdByMetazone(const UnicodeString &mzid, const UnicodeString ®ion, UnicodeString &result) { 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *tzid = NULL; 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tzidLen = 0; 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char keyBuf[ZID_KEY_MAX + 1]; 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t keyLen = 0; 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzid.length() > ZID_KEY_MAX) { 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setToBogus(); 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyLen = mzid.extract(0, mzid.length(), keyBuf, ZID_KEY_MAX + 1, US_INV); 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyBuf[keyLen] = 0; 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gMapTimezonesTag, rb, &status); 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, keyBuf, rb, &status); 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // check region mapping 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (region.length() == 2 || region.length() == 3) { 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyLen = region.extract(0, region.length(), keyBuf, ZID_KEY_MAX + 1, US_INV); 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyBuf[keyLen] = 0; 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzid = ures_getStringByKey(rb, keyBuf, &tzidLen, &status); 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (status == U_MISSING_RESOURCE_ERROR) { 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && tzid == NULL) { 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // try "001" 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzid = ures_getStringByKey(rb, gWorldTag, &tzidLen, &status); 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rb); 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzid == NULL) { 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setToBogus(); 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setTo(tzid, tzidLen); 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV initAvailableMetaZoneIDs () { 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(gMetaZoneIDs == NULL); 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(gMetaZoneIDTable == NULL); 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup); 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status); 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || gMetaZoneIDTable == NULL) { 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDTable = NULL; 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setKeyDeleter(gMetaZoneIDTable, uprv_deleteUObject); 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No valueDeleter, because the vector maintain the value objects 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDs = new UVector(NULL, uhash_compareUChars, status); 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || gMetaZoneIDs == NULL) { 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDs = NULL; 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(gMetaZoneIDTable); 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDTable = NULL; 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDs->setDeleter(uprv_free); 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status); 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle res; 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_initStackObject(&res); 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (U_SUCCESS(status) && ures_hasNext(bundle)) { 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getNextResource(bundle, &res, &status); 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *mzID = ures_getKey(&res); 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = uprv_strlen(mzID); 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1)); 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (uMzID == NULL) { 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_charsToUChars(mzID, uMzID, len); 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uMzID[len] = 0; 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString *usMzID = new UnicodeString(uMzID); 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (uhash_get(gMetaZoneIDTable, usMzID) == NULL) { 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDs->addElement((void *)uMzID, status); 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_put(gMetaZoneIDTable, (void *)usMzID, (void *)uMzID, &status); 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(uMzID); 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete usMzID; 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(&res); 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(bundle); 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rb); 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(gMetaZoneIDTable); 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gMetaZoneIDs; 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDTable = NULL; 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMetaZoneIDs = NULL; 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UVector* 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getAvailableMetazoneIDs() { 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gMetaZoneIDsInitOnce, &initAvailableMetaZoneIDs); 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return gMetaZoneIDs; 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::findMetaZoneID(const UnicodeString& mzid) { 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gMetaZoneIDsInitOnce, &initAvailableMetaZoneIDs); 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gMetaZoneIDTable == NULL) { 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (const UChar*)uhash_get(gMetaZoneIDTable, &mzid); 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::findTimeZoneID(const UnicodeString& tzid) { 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TimeZone::findID(tzid); 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZone* 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::createCustomTimeZone(int32_t offset) { 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool negative = FALSE; 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tmp = offset; 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset < 0) { 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org negative = TRUE; 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmp = -offset; 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t hour, min, sec; 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmp /= 1000; 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sec = tmp % 60; 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmp /= 60; 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org min = tmp % 60; 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hour = tmp / 60; 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString zid; 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatCustomID(hour, min, sec, negative, zid); 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new SimpleTimeZone(offset, zid); 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::formatCustomID(uint8_t hour, uint8_t min, uint8_t sec, UBool negative, UnicodeString& id) { 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Create normalized time zone ID - GMT[+|-]HH:mm[:ss] 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.setTo(gCustomTzPrefix, -1); 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (hour != 0 || min != 0) { 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (negative) { 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)0x2D); // '-' 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)0x2B); // '+' 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Always use US-ASCII digits 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)(0x30 + (hour%100)/10)); 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)(0x30 + (hour%10))); 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)0x3A); // ':' 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)(0x30 + (min%100)/10)); 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)(0x30 + (min%10))); 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sec != 0) { 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)0x3A); // ':' 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)(0x30 + (sec%100)/10)); 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org id.append((UChar)(0x30 + (sec%10))); 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return id; 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getShortID(const TimeZone& tz) { 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* canonicalID = NULL; 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL) { 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // short cut for OlsonTimeZone 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const OlsonTimeZone *otz = (const OlsonTimeZone*)&tz; 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org canonicalID = otz->getCanonicalID(); 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (canonicalID == NULL) { 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return getShortIDFromCanonical(canonicalID); 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getShortID(const UnicodeString& id) { 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(id, status); 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || canonicalID == NULL) { 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ZoneMeta::getShortIDFromCanonical(canonicalID); 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZoneMeta::getShortIDFromCanonical(const UChar* canonicalID) { 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* shortID = NULL; 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = u_strlen(canonicalID); 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char tzidKey[ZID_KEY_MAX + 1]; 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_UCharsToChars(canonicalID, tzidKey, len); 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzidKey[len] = (char) 0; // Make sure it is null terminated. 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // replace '/' with ':' 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *p = tzidKey; 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*p++) { 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*p == '/') { 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *p = ':'; 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *rb = ures_openDirect(NULL, gKeyTypeData, &status); 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gTypeMapTag, rb, &status); 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(rb, gTimezoneTag, rb, &status); 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org shortID = ures_getStringByKey(rb, tzidKey, NULL, &status); 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rb); 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return shortID; 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 940