1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2007-2010, International Business Machines Corporation and * 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* others. All Rights Reserved. * 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "zstrfmt.h" 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h" 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/msgfmt.h" 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/basictz.h" 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/simpletz.h" 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/rbtz.h" 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/vtzone.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uvector.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uresimp.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "zonemeta.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "olsontz.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucln_in.h" 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uassert.h" 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ureslocs.h" 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * global ZoneStringFormatCache stuffs 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX gZSFCacheLock = NULL; 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_NAMESPACE_QUALIFIER ZSFCache *gZoneStringFormatCache = NULL; 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ZoneStringFormatCache cleanup callback func 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool U_CALLCONV zoneStringFormat_cleanup(void) 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_destroy(&gZSFCacheLock); 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (gZoneStringFormatCache != NULL) { 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete gZoneStringFormatCache; 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gZoneStringFormatCache = NULL; 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gZoneStringFormatCache = NULL; 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Deleter for ZoneStringInfo 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)deleteZoneStringInfo(void *obj) { 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete (U_NAMESPACE_QUALIFIER ZoneStringInfo*)obj; 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Deleter for ZoneStrings 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)deleteZoneStrings(void *obj) { 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete (U_NAMESPACE_QUALIFIER ZoneStrings*)obj; 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_END 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ZID_KEY_MAX 128 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gCountriesTag[] = "Countries"; 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gZoneStringsTag[] = "zoneStrings"; 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gShortGenericTag[] = "sg"; 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gShortStandardTag[] = "ss"; 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gShortDaylightTag[] = "sd"; 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gLongGenericTag[] = "lg"; 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gLongStandardTag[] = "ls"; 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gLongDaylightTag[] = "ld"; 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gExemplarCityTag[] = "ec"; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gCommonlyUsedTag[] = "cu"; 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gFallbackFormatTag[] = "fallbackFormat"; 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gRegionFormatTag[] = "regionFormat"; 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MZID_PREFIX_LEN 5 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gMetazoneIdPrefix[] = "meta:"; 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_METAZONES_PER_ZONE 10 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefFallbackPattern[] = {0x7B, 0x31, 0x7D, 0x20, 0x28, 0x7B, 0x30, 0x7D, 0x29, 0x00}; // "{1} ({0})" 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefRegionPattern[] = {0x7B, 0x30, 0x7D, 0x00}; // "{0}" 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gCommonlyUsedTrue[] = {0x31, 0x00}; // "1" 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const double kDstCheckRange = (double)184*U_MILLIS_PER_DAY; 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTimeZoneTranslationTypeIndex(TimeZoneTranslationType type) { 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t typeIdx = 0; 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (type) { 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case LOCATION: 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LOCATION; 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case GENERIC_LONG: 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LONG_GENERIC; 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case GENERIC_SHORT: 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_SHORT_GENERIC; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case STANDARD_LONG: 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LONG_STANDARD; 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case STANDARD_SHORT: 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_SHORT_STANDARD; 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case DAYLIGHT_LONG: 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LONG_DAYLIGHT; 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case DAYLIGHT_SHORT: 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_SHORT_DAYLIGHT; 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return typeIdx; 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTimeZoneTranslationType(TimeZoneTranslationTypeIndex typeIdx) { 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t type = 0; 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (typeIdx) { 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LOCATION: 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = LOCATION; 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_GENERIC: 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = GENERIC_LONG; 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_GENERIC: 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = GENERIC_SHORT; 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_STANDARD: 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = STANDARD_LONG; 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_STANDARD: 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = STANDARD_SHORT; 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_DAYLIGHT: 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = DAYLIGHT_LONG; 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_COUNT: 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_DAYLIGHT: 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = DAYLIGHT_SHORT; 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return type; 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DEFAULT_CHARACTERNODE_CAPACITY 1 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ---------------------------------------------------------------------------- 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void CharacterNode::clear() { 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memset(this, 0, sizeof(*this)); 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void CharacterNode::deleteValues() { 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fValues == NULL) { 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Do nothing. 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (!fHasValuesVector) { 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) deleteZoneStringInfo(fValues); 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete (UVector *)fValues; 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CharacterNode::addValue(void *value, UErrorCode &status) { 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) deleteZoneStringInfo(value); 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fValues == NULL) { 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fValues = value; 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // At least one value already. 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!fHasValuesVector) { 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // There is only one value so far, and not in a vector yet. 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create a vector and add the old value. 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UVector *values = new UVector(deleteZoneStringInfo, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status); 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) deleteZoneStringInfo(value); 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) values->addElement(fValues, status); 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fValues = values; 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fHasValuesVector = TRUE; 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add the new value. 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UVector *)fValues)->addElement(value, status); 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------------------------------------- 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Virtual destructor to avoid warning 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMapSearchResultHandler::~TextTrieMapSearchResultHandler(){ 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ---------------------------------------------------------------------------- 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::TextTrieMap(UBool ignoreCase) 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fIgnoreCase(ignoreCase), fNodes(NULL), fNodesCapacity(0), fNodesCount(0), 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLazyContents(NULL), fIsEmpty(TRUE) { 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::~TextTrieMap() { 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t index; 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (index = 0; index < fNodesCount; ++index) { 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodes[index].deleteValues(); 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(fNodes); 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fLazyContents != NULL) { 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i=0; i<fLazyContents->size(); i+=2) { 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinf = (ZoneStringInfo *)fLazyContents->elementAt(i+1); 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zsinf; 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete fLazyContents; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t TextTrieMap::isEmpty() const { 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use a separate field for fIsEmpty because it will remain unchanged once the 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Trie is built, while fNodes and fLazyContents change with the lazy init 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // of the nodes structure. Trying to test the changing fields has 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // thread safety complications. 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return fIsEmpty; 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// We defer actually building the TextTrieMap node structure until the first time a 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// search is performed. put() simply saves the parameters in case we do 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// eventually need to build it. 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::put(const UnicodeString &key, void *value, ZSFStringPool &sp, UErrorCode &status) { 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fIsEmpty = FALSE; 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fLazyContents == NULL) { 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLazyContents = new UVector(status); 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fLazyContents == NULL) { 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *s = const_cast<UChar *>(sp.get(key, status)); 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLazyContents->addElement(s, status); 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLazyContents->addElement(value, status); 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::putImpl(const UnicodeString &key, void *value, UErrorCode &status) { 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fNodes == NULL) { 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodesCapacity = 512; 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodes = (CharacterNode *)uprv_malloc(fNodesCapacity * sizeof(CharacterNode)); 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodes[0].clear(); // Init root node. 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodesCount = 1; 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString foldedKey; 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *keyBuffer; 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t keyLength; 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fIgnoreCase) { 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Ok to use fastCopyFrom() because we discard the copy when we return. 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) foldedKey.fastCopyFrom(key).foldCase(); 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) keyBuffer = foldedKey.getBuffer(); 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) keyLength = foldedKey.length(); 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) keyBuffer = key.getBuffer(); 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) keyLength = key.length(); 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CharacterNode *node = fNodes; 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t index; 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (index = 0; index < keyLength; ++index) { 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = addChildNode(node, keyBuffer[index], status); 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node->addValue(value, status); 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::growNodes() { 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fNodesCapacity == 0xffff) { 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; // We use 16-bit node indexes. 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t newCapacity = fNodesCapacity + 1000; 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (newCapacity > 0xffff) { 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newCapacity = 0xffff; 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CharacterNode *newNodes = (CharacterNode *)uprv_malloc(newCapacity * sizeof(CharacterNode)); 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (newNodes == NULL) { 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(newNodes, fNodes, fNodesCount * sizeof(CharacterNode)); 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(fNodes); 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodes = newNodes; 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodesCapacity = newCapacity; 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CharacterNode* 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::addChildNode(CharacterNode *parent, UChar c, UErrorCode &status) { 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Linear search of the sorted list of children. 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t prevIndex = 0; 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t nodeIndex = parent->fFirstChild; 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (nodeIndex > 0) { 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CharacterNode *current = fNodes + nodeIndex; 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar childCharacter = current->fCharacter; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (childCharacter == c) { 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return current; 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (childCharacter > c) { 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prevIndex = nodeIndex; 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nodeIndex = current->fNextSibling; 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Ensure capacity. Grow fNodes[] if needed. 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fNodesCount == fNodesCapacity) { 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t parentIndex = (int32_t)(parent - fNodes); 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!growNodes()) { 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parent = fNodes + parentIndex; 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Insert a new child node with c in sorted order. 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CharacterNode *node = fNodes + fNodesCount; 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node->clear(); 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node->fCharacter = c; 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node->fNextSibling = nodeIndex; 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (prevIndex == 0) { 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parent->fFirstChild = (uint16_t)fNodesCount; 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNodes[prevIndex].fNextSibling = (uint16_t)fNodesCount; 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++fNodesCount; 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return node; 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CharacterNode* 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::getChildNode(CharacterNode *parent, UChar c) const { 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Linear search of the sorted list of children. 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t nodeIndex = parent->fFirstChild; 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (nodeIndex > 0) { 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CharacterNode *current = fNodes + nodeIndex; 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar childCharacter = current->fCharacter; 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (childCharacter == c) { 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return current; 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (childCharacter > c) { 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nodeIndex = current->fNextSibling; 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Mutex for protecting the lazy creation of the Trie node structure on the first call to search(). 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX TextTrieMutex; 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// buildTrie() - The Trie node structure is needed. Create it from the data that was 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// saved at the time the ZoneStringFormatter was created. The Trie is only 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// needed for parsing operations, which are less common than formatting, 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// and the Trie is big, which is why its creation is deferred until first use. 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void TextTrieMap::buildTrie(UErrorCode &status) { 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&TextTrieMutex); 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fLazyContents != NULL) { 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i=0; i<fLazyContents->size(); i+=2) { 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *key = (UChar *)fLazyContents->elementAt(i); 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *val = fLazyContents->elementAt(i+1); 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString keyString(TRUE, key, -1); // Aliasing UnicodeString constructor. 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) putImpl(keyString, val, status); 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete fLazyContents; 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLazyContents = NULL; 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&TextTrieMutex); 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::search(const UnicodeString &text, int32_t start, 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool trieNeedsInitialization = FALSE; 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UMTX_CHECK(&TextTrieMutex, fLazyContents != NULL, trieNeedsInitialization); 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (trieNeedsInitialization) { 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this); 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nonConstThis->buildTrie(status); 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fNodes == NULL) { 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) search(fNodes, text, start, start, handler, status); 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)TextTrieMap::search(CharacterNode *node, const UnicodeString &text, int32_t start, 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (node->hasValues()) { 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!handler->handleMatch(index - start, node, status)) { 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c = text.char32At(index); 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fIgnoreCase) { 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // size of character may grow after fold operation 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString tmp(c); 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmp.foldCase(); 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t tmpidx = 0; 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (tmpidx < tmp.length()) { 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c = tmp.char32At(tmpidx); 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = getChildNode(node, c); 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (node == NULL) { 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmpidx = tmp.moveIndex32(tmpidx, 1); 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = getChildNode(node, c); 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (node != NULL) { 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) search(node, text, start, index+1, handler, status); 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ---------------------------------------------------------------------------- 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringInfo::ZoneStringInfo(const UnicodeString &id, const UnicodeString &str, 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZoneTranslationType type, ZSFStringPool &sp, UErrorCode &status) 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fType(type) { 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fId = sp.get(id, status); 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStr = sp.get(str, status); 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringInfo::~ZoneStringInfo() { 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ---------------------------------------------------------------------------- 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringSearchResultHandler::ZoneStringSearchResultHandler(UErrorCode &status) 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fResults(status) 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) clear(); 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringSearchResultHandler::~ZoneStringSearchResultHandler() { 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) clear(); 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringSearchResultHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (node->hasValues()) { 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t valuesCount = node->countValues(); 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < valuesCount; i++) { 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinfo = (ZoneStringInfo*)node->getValue(i); 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zsinfo == NULL) { 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Update the results 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool foundType = FALSE; 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t j = 0; j < fResults.size(); j++) { 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *tmp = (ZoneStringInfo*)fResults.elementAt(j); 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zsinfo->fType == tmp->fType) { 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t lenidx = getTimeZoneTranslationTypeIndex(tmp->fType); 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (matchLength > fMatchLen[lenidx]) { 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Same type, longer match 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fResults.setElementAt(zsinfo, j); 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMatchLen[lenidx] = matchLength; 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) foundType = TRUE; 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!foundType) { 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // not found in the current list 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fResults.addElement(zsinfo, status); 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMatchLen[getTimeZoneTranslationTypeIndex(zsinfo->fType)] = matchLength; 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringSearchResultHandler::countMatches(void) { 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return fResults.size(); 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringSearchResultHandler::getMatch(int32_t index, int32_t &matchLength) { 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinfo = NULL; 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (index < fResults.size()) { 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zsinfo = (ZoneStringInfo*)fResults.elementAt(index); 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) matchLength = fMatchLen[getTimeZoneTranslationTypeIndex(zsinfo->fType)]; 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return zsinfo; 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringSearchResultHandler::clear(void) { 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fResults.removeAllElements(); 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < (int32_t)(sizeof(fMatchLen)/sizeof(fMatchLen[0])); i++) { 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMatchLen[i] = 0; 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Mutex for protecting the lazy load of a zone ID (or a full load) to ZoneStringFormat structures. 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX ZoneStringFormatMutex; 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ---------------------------------------------------------------------------- 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::ZoneStringFormat(const UnicodeString* const* strings, 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rowCount, int32_t columnCount, UErrorCode &status) 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fLocale(""), 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fTzidToStrings(NULL), 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMzidToStrings(NULL), 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie(TRUE), 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool(status), 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray(NULL), 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMetazoneItem(NULL), 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneItem(NULL), 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fIsFullyLoaded(FALSE) 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLocale.setToBogus(); 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (strings == NULL || columnCount <= 0 || rowCount <= 0) { 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ILLEGAL_ARGUMENT_ERROR; 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fTzidToStrings = uhash_open(uhash_hashUChars, // key hash function 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_compareUChars, // key comparison function 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, // Value comparison function 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMzidToStrings = uhash_open(uhash_hashUChars, 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_compareUChars, 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_setValueDeleter(fTzidToStrings, deleteZoneStrings); 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_setValueDeleter(fMzidToStrings, deleteZoneStrings); 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t row = 0; row < rowCount; row++) { 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (strings[row][0].isEmpty()) { 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString *names = new UnicodeString[ZSIDX_COUNT]; 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t col = 1; col < columnCount; col++) { 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!strings[row][col].isEmpty()) { 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t typeIdx = -1; 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (col) { 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 1: 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LONG_STANDARD; 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 2: 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_SHORT_STANDARD; 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 3: 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LONG_DAYLIGHT; 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 4: 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_SHORT_DAYLIGHT; 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 5: 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LOCATION; 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 6: 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_LONG_GENERIC; 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 7: 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typeIdx = ZSIDX_SHORT_GENERIC; 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (typeIdx != -1) { 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) names[typeIdx].setTo(strings[row][col]); 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Put the name into the trie 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t type = getTimeZoneTranslationType((TimeZoneTranslationTypeIndex)typeIdx); 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinf = new ZoneStringInfo(strings[row][0], 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings[row][col], 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (TimeZoneTranslationType)type, 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool, 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie.put(strings[row][col], zsinf, fStringPool, status); 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zsinf; 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Note: ZoneStrings constructor adopts and delete the names array. 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = new ZoneStrings(names, ZSIDX_COUNT, TRUE, NULL, 0, 0, 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool, status); 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *utzid = const_cast<UChar *>(fStringPool.get(strings[row][0], status)); 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_put(fTzidToStrings, utzid, zstrings, &status); 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zstrings; 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool.freeze(); 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fIsFullyLoaded = TRUE; 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)error_cleanup: 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::ZoneStringFormat(const Locale &locale, UErrorCode &status) 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fLocale(locale), 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fTzidToStrings(NULL), 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMzidToStrings(NULL), 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie(TRUE), 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool(status), 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray(NULL), 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMetazoneItem(NULL), 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneItem(NULL), 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fIsFullyLoaded(FALSE) 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fTzidToStrings = uhash_open(uhash_hashUChars, // key hash function 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_compareUChars, // key comparison function 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, // Value comparison function 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMzidToStrings = uhash_open(uhash_hashUChars, // key hash function 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_compareUChars, // key comparison function 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, // Value comparison function 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_setValueDeleter(fTzidToStrings, deleteZoneStrings); 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_setValueDeleter(fMzidToStrings, deleteZoneStrings); 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Load only a single zone 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::loadZone(const UnicodeString &utzid, UErrorCode &status) 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fIsFullyLoaded) { 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&ZoneStringFormatMutex); 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fZoneStringsArray == NULL) { 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray = ures_open(U_ICUDATA_ZONE, fLocale.getName(), &status); 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray = ures_getByKeyWithFallback(fZoneStringsArray, gZoneStringsTag, fZoneStringsArray, &status); 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If no locale bundles are available, zoneStrings will be null. 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We still want to go through the rest of zone strings initialization, 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // because generic location format is generated from tzid for the case. 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The rest of code should work even zoneStrings is null. 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(fZoneStringsArray); 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray = NULL; 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Skip non-canonical IDs 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonicalID; 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone::getCanonicalID(utzid, canonicalID, status); 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Ignore unknown ID - we should not get here, but just in case. 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // status = U_ZERO_ERROR; 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&ZoneStringFormatMutex); 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uhash_count(fTzidToStrings) > 0) { 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer()); 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrings != NULL) { 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&ZoneStringFormatMutex); 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; // We already about this one 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) addSingleZone(canonicalID, status); 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&ZoneStringFormatMutex); 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Load only a single zone 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::addSingleZone(UnicodeString &utzid, UErrorCode &status) 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uhash_count(fTzidToStrings) > 0) { 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, utzid.getTerminatedBuffer()); 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrings != NULL) { 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; // We already about this one 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MessageFormat *fallbackFmt = NULL; 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MessageFormat *regionFmt = NULL; 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallbackFmt = getFallbackFormat(fLocale, status); 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) regionFmt = getRegionFormat(fLocale, status); 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char zidkey[ZID_KEY_MAX+1]; 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char tzid[ZID_KEY_MAX+1]; 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) utzid.extract(0, utzid.length(), zidkey, ZID_KEY_MAX, US_INV); 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) utzid.extract(0, utzid.length(), tzid, ZID_KEY_MAX, US_INV); 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *zstrarray[ZSIDX_COUNT]; 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *mzstrarray[ZSIDX_COUNT]; 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString mzPartialLoc[MAX_METAZONES_PER_ZONE][4]; 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Replace '/' with ':' 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *pCity = NULL; 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *p = zidkey; 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (*p) { 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (*p == '/') { 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *p = ':'; 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCity = p + 1; 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) p++; 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fZoneStringsArray != NULL) { 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneItem = ures_getByKeyWithFallback(fZoneStringsArray, zidkey, fZoneItem, &status); 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If failed to open the zone item, create only location string 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(fZoneItem); 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneItem = NULL; 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString region; 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getRegion(region); 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LONG_STANDARD] = getZoneStringFromBundle(fZoneItem, gLongStandardTag); 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_SHORT_STANDARD] = getZoneStringFromBundle(fZoneItem, gShortStandardTag); 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LONG_DAYLIGHT] = getZoneStringFromBundle(fZoneItem, gLongDaylightTag); 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_SHORT_DAYLIGHT] = getZoneStringFromBundle(fZoneItem, gShortDaylightTag); 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LONG_GENERIC] = getZoneStringFromBundle(fZoneItem, gLongGenericTag); 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_SHORT_GENERIC] = getZoneStringFromBundle(fZoneItem, gShortGenericTag); 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Compose location format string 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString location; 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString country; 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString city; 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString countryCode; 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getCanonicalCountry(utzid, countryCode); 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!countryCode.isEmpty()) { 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar* tmpCity = getZoneStringFromBundle(fZoneItem, gExemplarCityTag); 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (tmpCity != NULL) { 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) city.setTo(TRUE, tmpCity, -1); 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) city.setTo(UnicodeString(pCity, -1, US_INV)); 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Replace '_' with ' ' 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < city.length(); i++) { 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (city.charAt(i) == (UChar)0x5F /*'_'*/) { 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) city.setCharAt(i, (UChar)0x20 /*' '*/); 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getLocalizedCountry(countryCode, fLocale, country); 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString singleCountry; 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getSingleCountry(utzid, singleCountry); 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FieldPosition fpos; 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (singleCountry.isEmpty()) { 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable params [] = { 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(city), 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(country) 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallbackFmt->format(params, 2, location, fpos, status); 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If the zone is only one zone in the country, do not add city 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable params [] = { 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(country) 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) regionFmt->format(params, 1, location, fpos, status); 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LOCATION] = location.getTerminatedBuffer(); 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uprv_strlen(tzid) > 4 && uprv_strncmp(tzid, "Etc/", 4) == 0) { 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // "Etc/xxx" is not associated with a specific location, so localized 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // GMT format is always used as generic location format. 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LOCATION] = NULL; 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // When a new time zone ID, which is actually associated with a specific 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // location, is added in tzdata, but the current CLDR data does not have 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the information yet, ICU creates a generic location string based on 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the ID. This implementation supports canonical time zone round trip 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // with format pattern "VVVV". See #6602 for the details. 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString loc(utzid); 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t slashIdx = loc.lastIndexOf((UChar)0x2f); 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (slashIdx == -1) { 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // A time zone ID without slash in the tz database is not 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // associated with a specific location. For instances, 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // MET, CET, EET and WET fall into this category. 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // In this case, we still use GMT format as fallback. 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LOCATION] = NULL; 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FieldPosition fpos; 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable params[] = { 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(loc) 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) regionFmt->format(params, 1, location, fpos, status); 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrarray[ZSIDX_LOCATION] = location.getTerminatedBuffer(); 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool commonlyUsed = isCommonlyUsed(fZoneItem); 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Resolve metazones used by this zone 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t mzPartialLocIdx = 0; 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UVector *metazoneMappings = ZoneMeta::getMetazoneMappings(utzid); 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (metazoneMappings != NULL) { 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < metazoneMappings->size(); i++) { 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const OlsonToMetaMappingEntry *mzmap = 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (const OlsonToMetaMappingEntry*)metazoneMappings->elementAt(i); 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString mzid(mzmap->mzid); 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ZoneStrings *mzStrings = 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (const ZoneStrings*)uhash_get(fMzidToStrings, mzid.getTerminatedBuffer()); 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzStrings == NULL) { 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If the metazone strings are not yet processed, do it now. 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char mzidkey[ZID_KEY_MAX]; 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_strcpy(mzidkey, gMetazoneIdPrefix); 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_UCharsToChars(mzmap->mzid, mzidkey + MZID_PREFIX_LEN, u_strlen(mzmap->mzid) + 1); 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fMetazoneItem = ures_getByKeyWithFallback(fZoneStringsArray, mzidkey, fMetazoneItem, &status); 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // No resources available for this metazone 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Resource bundle will be cleaned up after end of the loop. 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool mzCommonlyUsed = isCommonlyUsed(fMetazoneItem); 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_LONG_STANDARD] = getZoneStringFromBundle(fMetazoneItem, gLongStandardTag); 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_SHORT_STANDARD] = getZoneStringFromBundle(fMetazoneItem, gShortStandardTag); 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_LONG_DAYLIGHT] = getZoneStringFromBundle(fMetazoneItem, gLongDaylightTag); 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_SHORT_DAYLIGHT] = getZoneStringFromBundle(fMetazoneItem, gShortDaylightTag); 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_LONG_GENERIC] = getZoneStringFromBundle(fMetazoneItem, gLongGenericTag); 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_SHORT_GENERIC] = getZoneStringFromBundle(fMetazoneItem, gShortGenericTag); 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrarray[ZSIDX_LOCATION] = NULL; 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t lastNonNullIdx = ZSIDX_COUNT - 1; 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (lastNonNullIdx >= 0) { 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzstrarray[lastNonNullIdx] != NULL) { 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lastNonNullIdx--; 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString *strings_mz = NULL; 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *tmp_mzStrings = NULL; 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (lastNonNullIdx >= 0) { 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create UnicodeString array and put strings to the zone string trie 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings_mz = new UnicodeString[lastNonNullIdx + 1]; 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString preferredIdForLocale; 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getZoneIdByMetazone(mzid, region, preferredIdForLocale); 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t typeidx = 0; typeidx <= lastNonNullIdx; typeidx++) { 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzstrarray[typeidx] != NULL) { 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings_mz[typeidx].setTo(TRUE, mzstrarray[typeidx], -1); 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add a metazone string to the zone string trie 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t type = getTimeZoneTranslationType((TimeZoneTranslationTypeIndex)typeidx); 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinfo = new ZoneStringInfo( 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) preferredIdForLocale, 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings_mz[typeidx], 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (TimeZoneTranslationType)type, 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool, 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie.put(strings_mz[typeidx], zsinfo, fStringPool, status); 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete []strings_mz; 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Note: ZoneStrings constructor adopts and deletes the strings_mz array. 924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmp_mzStrings = new ZoneStrings(strings_mz, lastNonNullIdx + 1, 925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzCommonlyUsed, NULL, 0, 0, fStringPool, status); 926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create ZoneStrings with empty contents 928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmp_mzStrings = new ZoneStrings(NULL, 0, FALSE, NULL, 0, 0, fStringPool, status); 929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *umzid = const_cast<UChar *>(fStringPool.get(mzid, status)); 932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_put(fMzidToStrings, umzid, tmp_mzStrings, &status); 933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzStrings = tmp_mzStrings; 938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Compose generic partial location format 941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString lg; 942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString sg; 943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzStrings->getString(ZSIDX_LONG_GENERIC, lg); 945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzStrings->getString(ZSIDX_SHORT_GENERIC, sg); 946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!lg.isEmpty() || !sg.isEmpty()) { 948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool addMzPartialLocationNames = TRUE; 949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t j = 0; j < mzPartialLocIdx; j++) { 950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzPartialLoc[j][0] == mzid) { 951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // already processed 952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) addMzPartialLocationNames = FALSE; 953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (addMzPartialLocationNames) { 957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString *locationPart = NULL; 958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check if the zone is the preferred zone for the territory associated with the zone 959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString preferredID; 960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getZoneIdByMetazone(mzid, countryCode, preferredID); 961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (utzid == preferredID) { 962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use country for the location 963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) locationPart = &country; 964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use city for the location 966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) locationPart = &city; 967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Reset the partial location string array 969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzPartialLoc[mzPartialLocIdx][0].setTo(mzid); 970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzPartialLoc[mzPartialLocIdx][1].remove(); 971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzPartialLoc[mzPartialLocIdx][2].remove(); 972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzPartialLoc[mzPartialLocIdx][3].remove(); 973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (locationPart->length() != 0) { 975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FieldPosition fpos; 976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!lg.isEmpty()) { 977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable params [] = { 978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(*locationPart), 979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(lg) 980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallbackFmt->format(params, 2, mzPartialLoc[mzPartialLocIdx][1], fpos, status); 982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!sg.isEmpty()) { 984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable params [] = { 985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(*locationPart), 986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable(sg) 987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }; 988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallbackFmt->format(params, 2, mzPartialLoc[mzPartialLocIdx][2], fpos, status); 989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzStrings->isShortFormatCommonlyUsed()) { 990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzPartialLoc[mzPartialLocIdx][3].setTo(TRUE, gCommonlyUsedTrue, -1); 991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzPartialLocIdx++; 998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Collected names for a zone 1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create UnicodeString array for localized zone strings 1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t lastIdx = ZSIDX_COUNT - 1; 1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (lastIdx >= 0) { 1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrarray[lastIdx] != NULL) { 1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lastIdx--; 1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString *strings = NULL; 1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t stringsCount = lastIdx + 1; 1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (stringsCount > 0) { 1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings = new UnicodeString[stringsCount]; 1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < stringsCount; i++) { 1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrarray[i] != NULL) { 1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings[i].setTo(zstrarray[i], -1); 1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add names to the trie 1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t type = getTimeZoneTranslationType((TimeZoneTranslationTypeIndex)i); 1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinfo = new ZoneStringInfo(utzid, 1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings[i], 1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (TimeZoneTranslationType)type, 1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool, 1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie.put(strings[i], zsinfo, fStringPool, status); 1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zsinfo; 1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete[] strings; 1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create UnicodeString array for generic partial location strings 1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString **genericPartialLocationNames = NULL; 1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t genericPartialRowCount = mzPartialLocIdx; 1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t genericPartialColCount = 4; 1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (genericPartialRowCount != 0) { 1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) genericPartialLocationNames = 1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (UnicodeString**)uprv_malloc(genericPartialRowCount * sizeof(UnicodeString*)); 1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (genericPartialLocationNames == NULL) { 1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete[] strings; 1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < genericPartialRowCount; i++) { 1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) genericPartialLocationNames[i] = new UnicodeString[genericPartialColCount]; 1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t j = 0; j < genericPartialColCount; j++) { 1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) genericPartialLocationNames[i][j].setTo(mzPartialLoc[i][j]); 1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add names to the trie 1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ((j == 1 || j == 2) &&!genericPartialLocationNames[i][j].isEmpty()) { 1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringInfo *zsinfo; 1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZoneTranslationType type = (j == 1) ? GENERIC_LONG : GENERIC_SHORT; 1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zsinfo = new ZoneStringInfo(utzid, genericPartialLocationNames[i][j], type, 1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool, status); 1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie.put(genericPartialLocationNames[i][j], zsinfo, fStringPool, status); 1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete[] genericPartialLocationNames[i]; 1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(genericPartialLocationNames); 1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete[] strings; 1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Finally, create ZoneStrings instance and put it into the tzidToStinrgs map 1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = new ZoneStrings(strings, stringsCount, commonlyUsed, 1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) genericPartialLocationNames, genericPartialRowCount, 1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) genericPartialColCount, fStringPool, status); 1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *uutzid = const_cast<UChar *>(fStringPool.get(utzid, status)); 1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_put(fTzidToStrings, uutzid, zstrings, &status); 1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zstrings; 1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)error_cleanup: 1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fallbackFmt != NULL) { 1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete fallbackFmt; 1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (regionFmt != NULL) { 1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete regionFmt; 1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // fStringPool.freeze(); 1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::loadFull(UErrorCode &status) 1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fIsFullyLoaded) { 1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&ZoneStringFormatMutex); 1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fZoneStringsArray == NULL) { 1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray = ures_open(U_ICUDATA_ZONE, fLocale.getName(), &status); 1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray = ures_getByKeyWithFallback(fZoneStringsArray, gZoneStringsTag, fZoneStringsArray, &status); 1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If no locale bundles are available, zoneStrings will be null. 1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We still want to go through the rest of zone strings initialization, 1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // because generic location format is generated from tzid for the case. 1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The rest of code should work even zoneStrings is null. 1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(fZoneStringsArray); 1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsArray = NULL; 1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) StringEnumeration *tzids = NULL; 1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tzids = TimeZone::createEnumeration(); 1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *tzid; 1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while ((tzid = tzids->next(NULL, status))) { 1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Skip non-canonical IDs 1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString utzid(tzid, -1, US_INV); 1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonicalID; 1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone::getCanonicalID(utzid, canonicalID, status); 1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Ignore unknown ID - we should not get here, but just in case. 1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uhash_count(fTzidToStrings) > 0) { 1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer()); 1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrings != NULL) { 1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; // We already about this one 1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) addSingleZone(canonicalID, status); 1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto error_cleanup; 1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fIsFullyLoaded = TRUE; 1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)error_cleanup: 1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (tzids != NULL) { 1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tzids; 1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringPool.freeze(); 1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&ZoneStringFormatMutex); 1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::~ZoneStringFormat() { 1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_close(fTzidToStrings); 1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_close(fMzidToStrings); 1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(fZoneItem); 1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(fMetazoneItem); 1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(fZoneStringsArray); 1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SafeZoneStringFormatPtr* 1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getZoneStringFormat(const Locale& locale, UErrorCode &status) { 1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&gZSFCacheLock); 1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (gZoneStringFormatCache == NULL) { 1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gZoneStringFormatCache = new ZSFCache(10 /* capacity */); 1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucln_i18n_registerCleanup(UCLN_I18N_ZSFORMAT, zoneStringFormat_cleanup); 1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&gZSFCacheLock); 1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return gZoneStringFormatCache->get(locale, status); 1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString** 1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::createZoneStringsArray(UDate date, int32_t &rowCount, int32_t &colCount, UErrorCode &status) const { 1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringFormat *nonConstThis = const_cast<ZoneStringFormat *>(this); 1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nonConstThis->loadFull(status); 1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString **result = NULL; 1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rowCount = 0; 1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) colCount = 0; 1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Collect canonical time zone IDs 1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UVector canonicalIDs(uhash_deleteUnicodeString, uhash_compareUnicodeString, status); 1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) StringEnumeration *tzids = TimeZone::createEnumeration(); 1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *tzid; 1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while ((tzid = tzids->unext(NULL, status))) { 1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tzids; 1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString utzid(tzid); 1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonicalID; 1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone::getCanonicalID(UnicodeString(tzid), canonicalID, status); 1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Ignore unknown ID - we should not get here, but just in case. 1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (utzid == canonicalID) { 1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) canonicalIDs.addElement(new UnicodeString(utzid), status); 1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tzids; 1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tzids; 1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Allocate array 1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = (UnicodeString**)uprv_malloc(canonicalIDs.size() * sizeof(UnicodeString*)); 1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == NULL) { 1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < canonicalIDs.size(); i++) { 1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result[i] = new UnicodeString[8]; 1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString *id = (UnicodeString*)canonicalIDs.elementAt(i); 1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result[i][0].setTo(*id); 1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getLongStandard(*id, date, result[i][1]); 1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getShortStandard(*id, date, FALSE, result[i][2]); 1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getLongDaylight(*id, date, result[i][3]); 1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getShortDaylight(*id, date, FALSE, result[i][4]); 1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getGenericLocation(*id, result[i][5]); 1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getLongGenericNonLocation(*id, date, result[i][6]); 1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getShortGenericNonLocation(*id, date, FALSE, result[i][7]); 1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rowCount = canonicalIDs.size(); 1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) colCount = 8; 1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getSpecificLongString(const Calendar &cal, UnicodeString &result, 1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode &status) const { 1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString tzid; 1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cal.getTimeZone().getID(tzid); 1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate date = cal.getTime(status); 1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (cal.get(UCAL_DST_OFFSET, status) == 0) { 1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getString(tzid, ZSIDX_LONG_STANDARD, date, FALSE /*not used*/, result); 1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getString(tzid, ZSIDX_LONG_DAYLIGHT, date, FALSE /*not used*/, result); 1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getSpecificShortString(const Calendar &cal, UBool commonlyUsedOnly, 1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString &result, UErrorCode &status) const { 1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString tzid; 1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cal.getTimeZone().getID(tzid); 1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate date = cal.getTime(status); 1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (cal.get(UCAL_DST_OFFSET, status) == 0) { 1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getString(tzid, ZSIDX_SHORT_STANDARD, date, commonlyUsedOnly, result); 1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getString(tzid, ZSIDX_SHORT_DAYLIGHT, date, commonlyUsedOnly, result); 1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getGenericLongString(const Calendar &cal, UnicodeString &result, 1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode &status) const { 1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getGenericString(cal, FALSE /*long*/, FALSE /* not used */, result, status); 1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getGenericShortString(const Calendar &cal, UBool commonlyUsedOnly, 1297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString &result, UErrorCode &status) const { 1298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getGenericString(cal, TRUE /*short*/, commonlyUsedOnly, result, status); 1299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getGenericLocationString(const Calendar &cal, UnicodeString &result, 1303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode &status) const { 1304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString tzid; 1305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cal.getTimeZone().getID(tzid); 1306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate date = cal.getTime(status); 1307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getString(tzid, ZSIDX_LOCATION, date, FALSE /*not used*/, result); 1308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::findSpecificLong(const UnicodeString &text, int32_t start, 1312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return find(text, start, STANDARD_LONG | DAYLIGHT_LONG, matchLength, status); 1314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::findSpecificShort(const UnicodeString &text, int32_t start, 1318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return find(text, start, STANDARD_SHORT | DAYLIGHT_SHORT, matchLength, status); 1320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::findGenericLong(const UnicodeString &text, int32_t start, 1324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return find(text, start, GENERIC_LONG | STANDARD_LONG | LOCATION, matchLength, status); 1326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::findGenericShort(const UnicodeString &text, int32_t start, 1330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return find(text, start, GENERIC_SHORT | STANDARD_SHORT | LOCATION, matchLength, status); 1332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::findGenericLocation(const UnicodeString &text, int32_t start, 1336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return find(text, start, LOCATION, matchLength, status); 1338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getString(const UnicodeString &tzid, TimeZoneTranslationTypeIndex typeIdx, UDate date, 1342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool commonlyUsedOnly, UnicodeString& result) const { 1343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!fIsFullyLoaded) { 1346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Lazy loading 1347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringFormat *nonConstThis = const_cast<ZoneStringFormat *>(this); 1348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nonConstThis->loadZone(tzid, status); 1349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ICU's own array does not have entries for aliases 1352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonicalID; 1353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone::getCanonicalID(tzid, canonicalID, status); 1354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Unknown ID, but users might have their own data. 1356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) canonicalID.setTo(tzid); 1357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uhash_count(fTzidToStrings) > 0) { 1360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer()); 1361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrings != NULL) { 1362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (typeIdx) { 1363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_STANDARD: 1364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_DAYLIGHT: 1365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_GENERIC: 1366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LOCATION: 1367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings->getString(typeIdx, result); 1368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_STANDARD: 1370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_DAYLIGHT: 1371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_COUNT: //added to avoid warning 1372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_GENERIC: 1373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!commonlyUsedOnly || zstrings->isShortFormatCommonlyUsed()) { 1374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings->getString(typeIdx, result); 1375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 1378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result.isEmpty() && uhash_count(fMzidToStrings) > 0 && typeIdx != ZSIDX_LOCATION) { 1383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Try metazone 1384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString mzid; 1385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getMetazoneID(canonicalID, date, mzid); 1386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!mzid.isEmpty()) { 1387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *mzstrings = (ZoneStrings*)uhash_get(fMzidToStrings, mzid.getTerminatedBuffer()); 1388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzstrings != NULL) { 1389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (typeIdx) { 1390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_STANDARD: 1391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_DAYLIGHT: 1392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LONG_GENERIC: 1393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_LOCATION: 1394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrings->getString(typeIdx, result); 1395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_STANDARD: 1397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_DAYLIGHT: 1398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_COUNT: //added to avoid warning 1399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ZSIDX_SHORT_GENERIC: 1400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!commonlyUsedOnly || mzstrings->isShortFormatCommonlyUsed()) { 1401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrings->getString(typeIdx, result); 1402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 1405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getGenericString(const Calendar &cal, UBool isShort, UBool commonlyUsedOnly, 1415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString &result, UErrorCode &status) const { 1416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate time = cal.getTime(status); 1418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const TimeZone &tz = cal.getTimeZone(); 1422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString tzid; 1423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tz.getID(tzid); 1424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!fIsFullyLoaded) { 1426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Lazy loading 1427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringFormat *nonConstThis = const_cast<ZoneStringFormat *>(this); 1428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nonConstThis->loadZone(tzid, status); 1429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ICU's own array does not have entries for aliases 1432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonicalID; 1433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone::getCanonicalID(tzid, canonicalID, status); 1434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Unknown ID, but users might have their own data. 1436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 1437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) canonicalID.setTo(tzid); 1438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = NULL; 1441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uhash_count(fTzidToStrings) > 0) { 1442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer()); 1443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrings != NULL) { 1444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (isShort) { 1445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!commonlyUsedOnly || zstrings->isShortFormatCommonlyUsed()) { 1446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings->getString(ZSIDX_SHORT_GENERIC, result); 1447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings->getString(ZSIDX_LONG_GENERIC, result); 1450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result.isEmpty() && uhash_count(fMzidToStrings) > 0) { 1454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // try metazone 1455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t raw, sav; 1456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString mzid; 1457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getMetazoneID(canonicalID, time, mzid); 1458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!mzid.isEmpty()) { 1459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool useStandard = FALSE; 1460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sav = cal.get(UCAL_DST_OFFSET, status); 1461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (sav == 0) { 1465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) useStandard = TRUE; 1466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check if the zone actually uses daylight saving time around the time 1467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone *tmptz = tz.clone(); 1468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) BasicTimeZone *btz = NULL; 1469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (dynamic_cast<OlsonTimeZone *>(tmptz) != NULL 1470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) || dynamic_cast<SimpleTimeZone *>(tmptz) != NULL 1471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) || dynamic_cast<RuleBasedTimeZone *>(tmptz) != NULL 1472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) || dynamic_cast<VTimeZone *>(tmptz) != NULL) { 1473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) btz = (BasicTimeZone*)tmptz; 1474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (btz != NULL) { 1477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZoneTransition before; 1478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool beforTrs = btz->getPreviousTransition(time, TRUE, before); 1479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (beforTrs 1480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) && (time - before.getTime() < kDstCheckRange) 1481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) && before.getFrom()->getDSTSavings() != 0) { 1482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) useStandard = FALSE; 1483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZoneTransition after; 1485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool afterTrs = btz->getNextTransition(time, FALSE, after); 1486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (afterTrs 1487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) && (after.getTime() - time < kDstCheckRange) 1488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) && after.getTo()->getDSTSavings() != 0) { 1489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) useStandard = FALSE; 1490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If not BasicTimeZone... only if the instance is not an ICU's implementation. 1494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We may get a wrong answer in edge case, but it should practically work OK. 1495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmptz->getOffset(time - kDstCheckRange, FALSE, raw, sav, status); 1496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (sav != 0) { 1497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) useStandard = FALSE; 1498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmptz->getOffset(time + kDstCheckRange, FALSE, raw, sav, status); 1500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (sav != 0){ 1501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) useStandard = FALSE; 1502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tmptz; 1506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tmptz; 1511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (useStandard) { 1513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getString(canonicalID, (isShort ? ZSIDX_SHORT_STANDARD : ZSIDX_LONG_STANDARD), 1514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) time, commonlyUsedOnly, result); 1515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Note: 1517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // In CLDR 1.5.1, a same localization is used for both generic and standard 1518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // for some metazones in some locales. This is actually data bugs and should 1519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // be resolved in later versions of CLDR. For now, we check if the standard 1520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // name is different from its generic name below. 1521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!result.isEmpty()) { 1522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString genericNonLocation; 1523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getString(canonicalID, (isShort ? ZSIDX_SHORT_GENERIC : ZSIDX_LONG_GENERIC), 1524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) time, commonlyUsedOnly, genericNonLocation); 1525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!genericNonLocation.isEmpty() && result == genericNonLocation) { 1526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result.isEmpty()) { 1531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *mzstrings = (ZoneStrings*)uhash_get(fMzidToStrings, mzid.getTerminatedBuffer()); 1532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzstrings != NULL) { 1533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (isShort) { 1534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!commonlyUsedOnly || mzstrings->isShortFormatCommonlyUsed()) { 1535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrings->getString(ZSIDX_SHORT_GENERIC, result); 1536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mzstrings->getString(ZSIDX_LONG_GENERIC, result); 1539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!result.isEmpty()) { 1542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check if the offsets at the given time matches the preferred zone's offsets 1543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString preferredId; 1544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString region; 1545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getZoneIdByMetazone(mzid, getRegion(region), preferredId); 1546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (canonicalID != preferredId) { 1547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check if the offsets at the given time are identical with the preferred zone 1548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) raw = cal.get(UCAL_ZONE_OFFSET, status); 1549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone *preferredZone = TimeZone::createTimeZone(preferredId); 1554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prfRaw, prfSav; 1555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check offset in preferred time zone with wall time. 1556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // With getOffset(time, false, preferredOffsets), 1557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // you may get incorrect results because of time overlap at DST->STD 1558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // transition. 1559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) preferredZone->getOffset(time + raw + sav, TRUE, prfRaw, prfSav, status); 1560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete preferredZone; 1561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ((raw != prfRaw || sav != prfSav) && zstrings != NULL) { 1567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use generic partial location string as fallback 1568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings->getGenericPartialLocationString(mzid, isShort, commonlyUsedOnly, result); 1569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result.isEmpty()) { 1576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use location format as the final fallback 1577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) getString(canonicalID, ZSIDX_LOCATION, time, FALSE /*not used*/, result); 1578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getGenericPartialLocationString(const UnicodeString &tzid, UBool isShort, 1585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate date, UBool commonlyUsedOnly, UnicodeString &result) const { 1586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!fIsFullyLoaded) { 1589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Lazy loading 1590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringFormat *nonConstThis = const_cast<ZoneStringFormat *>(this); 1591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nonConstThis->loadZone(tzid, status); 1592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uhash_count(fTzidToStrings) <= 0) { 1595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonicalID; 1599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TimeZone::getCanonicalID(tzid, canonicalID, status); 1600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Unknown ID, so no corresponding meta data. 1602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString mzid; 1606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneMeta::getMetazoneID(canonicalID, date, mzid); 1607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!mzid.isEmpty()) { 1609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer()); 1610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zstrings != NULL) { 1611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zstrings->getGenericPartialLocationString(mzid, isShort, commonlyUsedOnly, result); 1612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// This method does lazy zone string loading 1618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::find(const UnicodeString &text, int32_t start, int32_t types, 1620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ZoneStringInfo * result = subFind(text, start, types, matchLength, status); 1627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fIsFullyLoaded) { 1628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // When zone string data is partially loaded, 1631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // this method return the result only when 1632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the input text is fully consumed. 1633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result != NULL) { 1634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString tmpString; 1635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) matchLength = (result->getString(tmpString)).length(); 1636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (text.length() - start == matchLength) { 1637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Now load all zone strings 1642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringFormat *nonConstThis = const_cast<ZoneStringFormat *>(this); 1643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nonConstThis->loadFull(status); 1644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return subFind(text, start, types, matchLength, status); 1646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 1650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Find a prefix matching time zone for the given zone string types. 1651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text The text contains a time zone string 1652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param start The start index within the text 1653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param types The bit mask representing a set of requested types 1654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return If any zone string matched for the requested types, returns a 1655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ZoneStringInfo for the longest match. If no matches are found for 1656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the requested types, returns a ZoneStringInfo for the longest match 1657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * for any other types. If nothing matches at all, returns null. 1658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringInfo* 1660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::subFind(const UnicodeString &text, int32_t start, int32_t types, 1661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t &matchLength, UErrorCode &status) const { 1662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) matchLength = 0; 1663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fZoneStringsTrie.isEmpty()) { 1667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ZoneStringInfo *result = NULL; 1671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ZoneStringInfo *fallback = NULL; 1672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t fallbackMatchLen = 0; 1673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringSearchResultHandler handler(status); 1675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fZoneStringsTrie.search(text, start, (TextTrieMapSearchResultHandler*)&handler, status); 1676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t numMatches = handler.countMatches(); 1678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < numMatches; i++) { 1679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t tmpMatchLen = 0; // init. output only param to silence gcc 1680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ZoneStringInfo *tmp = handler.getMatch(i, tmpMatchLen); 1681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ((types & tmp->fType) != 0) { 1682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == NULL || matchLength < tmpMatchLen) { 1683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = tmp; 1684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) matchLength = tmpMatchLen; 1685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (matchLength == tmpMatchLen) { 1686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Tie breaker - there are some examples that a 1687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // long standard name is identical with a location 1688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // name - for example, "Uruguay Time". In this case, 1689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we interpret it as generic, not specific. 1690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (tmp->isGeneric() && !result->isGeneric()) { 1691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = tmp; 1692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (result == NULL) { 1695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fallback == NULL || fallbackMatchLen < tmpMatchLen) { 1696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallback = tmp; 1697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallbackMatchLen = tmpMatchLen; 1698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (fallbackMatchLen == tmpMatchLen) { 1699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (tmp->isGeneric() && !fallback->isGeneric()) { 1700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fallback = tmp; 1701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == NULL && fallback != NULL) { 1706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = fallback; 1707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) matchLength = fallbackMatchLen; 1708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getRegion(UnicodeString ®ion) const { 1716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char* country = fLocale.getCountry(); 1717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO: Utilize addLikelySubtag in Locale to resolve default region 1718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // when the implementation is ready. 1719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) region.setTo(UnicodeString(country, -1, US_INV)); 1720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return region; 1721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)MessageFormat* 1724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getFallbackFormat(const Locale &locale, UErrorCode &status) { 1725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString pattern(TRUE, gDefFallbackPattern, -1); 1729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *zoneStringsArray = ures_open(U_ICUDATA_ZONE, locale.getName(), &status); 1730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zoneStringsArray = ures_getByKeyWithFallback(zoneStringsArray, gZoneStringsTag, zoneStringsArray, &status); 1731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len; 1732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *flbkfmt = ures_getStringByKeyWithFallback(zoneStringsArray, gFallbackFormatTag, &len, &status); 1733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pattern.setTo(flbkfmt); 1735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 1737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(zoneStringsArray); 1739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MessageFormat *fallbackFmt = new MessageFormat(pattern, status); 1741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return fallbackFmt; 1742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)MessageFormat* 1745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getRegionFormat(const Locale& locale, UErrorCode &status) { 1746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString pattern(TRUE, gDefRegionPattern, -1); 1750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *zoneStringsArray = ures_open(U_ICUDATA_ZONE, locale.getName(), &status); 1751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) zoneStringsArray = ures_getByKeyWithFallback(zoneStringsArray, gZoneStringsTag, zoneStringsArray, &status); 1752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len; 1753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *regionfmt = ures_getStringByKeyWithFallback(zoneStringsArray, gRegionFormatTag, &len, &status); 1754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pattern.setTo(regionfmt); 1756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 1758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(zoneStringsArray); 1760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MessageFormat *regionFmt = new MessageFormat(pattern, status); 1762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return regionFmt; 1763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UChar* 1766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getZoneStringFromBundle(const UResourceBundle *zoneitem, const char *key) { 1767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *str = NULL; 1768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zoneitem != NULL) { 1769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len; 1771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) str = ures_getStringByKeyWithFallback(zoneitem, key, &len, &status); 1772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) str = fStringPool.adopt(str, status); 1773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) str = NULL; 1775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return str; 1778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 1781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::isCommonlyUsed(const UResourceBundle *zoneitem) { 1782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zoneitem == NULL) { 1783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 1784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool commonlyUsed = FALSE; 1787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *cuRes = ures_getByKey(zoneitem, gCommonlyUsedTag, NULL, &status); 1789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t cuValue = ures_getInt(cuRes, &status); 1790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (cuValue == 1) { 1792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) commonlyUsed = TRUE; 1793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(cuRes); 1796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return commonlyUsed; 1797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStringFormat::getLocalizedCountry(const UnicodeString &countryCode, const Locale &locale, UnicodeString &displayCountry) { 1801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We do not want to use display country names only from the target language bundle 1802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Note: we should do this in better way. 1803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) displayCountry.remove(); 1804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t ccLen = countryCode.length(); 1805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (ccLen > 0 && ccLen < ULOC_COUNTRY_CAPACITY) { 1806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &status); 1808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *bundleLocStr = ures_getLocale(localeBundle, &status); 1810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status) && uprv_strlen(bundleLocStr) > 0) { 1811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Locale bundleLoc(bundleLocStr); 1812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uprv_strcmp(bundleLocStr, "root") != 0 && 1813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_strcmp(bundleLoc.getLanguage(), locale.getLanguage()) == 0) { 1814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create a fake locale strings 1815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char tmpLocStr[ULOC_COUNTRY_CAPACITY + 3]; 1816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_strcpy(tmpLocStr, "xx_"); 1817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_UCharsToChars(countryCode.getBuffer(), &tmpLocStr[3], ccLen); 1818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmpLocStr[3 + ccLen] = 0; 1819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Locale tmpLoc(tmpLocStr); 1821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tmpLoc.getDisplayCountry(locale, displayCountry); 1822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(localeBundle); 1826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (displayCountry.isEmpty()) { 1828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use the country code as the fallback 1829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) displayCountry.setTo(countryCode); 1830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return displayCountry; 1832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ---------------------------------------------------------------------------- 1835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 1836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ZoneStrings constructor adopts (and promptly copies and deletes) 1837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the input UnicodeString arrays. 1838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStrings::ZoneStrings(UnicodeString *strings, 1840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t stringsCount, 1841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool commonlyUsed, 1842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString **genericPartialLocationStrings, 1843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t genericRowCount, 1844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t genericColCount, 1845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFStringPool &sp, 1846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode &status) 1847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fStrings(NULL), 1848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStringsCount(stringsCount), 1849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fIsCommonlyUsed(commonlyUsed), 1850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationStrings(NULL), 1851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationRowCount(genericRowCount), 1852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationColCount(genericColCount) 1853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 1854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i, j; 1858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (strings != NULL) { 1859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStrings = (const UChar **)uprv_malloc(sizeof(const UChar **) * stringsCount); 1860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fStrings == NULL) { 1861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (i=0; i<fStringsCount; i++) { 1865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fStrings[i] = sp.get(strings[i], status); 1866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete[] strings; 1868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (genericPartialLocationStrings != NULL) { 1870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationStrings = 1871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (const UChar ***)uprv_malloc(sizeof(const UChar ***) * genericRowCount); 1872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fGenericPartialLocationStrings == NULL) { 1873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (i=0; i < fGenericPartialLocationRowCount; i++) { 1877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationStrings[i] = 1878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (const UChar **)uprv_malloc(sizeof(const UChar **) * genericColCount); 1879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fGenericPartialLocationStrings[i] == NULL) { 1880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; // Continue so that fGenericPartialLocationStrings will not contain uninitialized junk, 1882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } // which would crash the destructor. 1883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (j=0; j<genericColCount; j++) { 1884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationStrings[i][j] = 1885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sp.get(genericPartialLocationStrings[i][j], status); 1886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete[] genericPartialLocationStrings[i]; 1888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(genericPartialLocationStrings); 1890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStrings::~ZoneStrings() { 1894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(fStrings); 1895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fGenericPartialLocationStrings != NULL) { 1896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < fGenericPartialLocationRowCount; i++) { 1897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(fGenericPartialLocationStrings[i]); 1898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(fGenericPartialLocationStrings); 1900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStrings::getString(int32_t typeIdx, UnicodeString &result) const { 1906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (typeIdx >= 0 && typeIdx < fStringsCount) { 1907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.setTo(fStrings[typeIdx], -1); 1908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& 1915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZoneStrings::getGenericPartialLocationString(const UnicodeString &mzid, UBool isShort, 1916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool commonlyUsedOnly, UnicodeString &result) const { 1917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isSet = FALSE; 1918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fGenericPartialLocationColCount >= 2) { 1919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < fGenericPartialLocationRowCount; i++) { 1920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (mzid.compare(fGenericPartialLocationStrings[i][0], -1) == 0) { 1921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (isShort) { 1922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fGenericPartialLocationColCount >= 3) { 1923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!commonlyUsedOnly || 1924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationColCount == 3 || 1925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fGenericPartialLocationStrings[i][3][0] != 0) { 1926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.setTo(fGenericPartialLocationStrings[i][2], -1); 1927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) isSet = TRUE; 1928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.setTo(fGenericPartialLocationStrings[i][1], -1); 1932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) isSet = TRUE; 1933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!isSet) { 1939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.remove(); 1940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// -------------------------------------------------------------- 1945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SafeZoneStringFormatPtr::SafeZoneStringFormatPtr(ZSFCacheEntry *cacheEntry) 1946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fCacheEntry(cacheEntry) { 1947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SafeZoneStringFormatPtr::~SafeZoneStringFormatPtr() { 1950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fCacheEntry->delRef(); 1951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringFormat* 1954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SafeZoneStringFormatPtr::get() const { 1955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return fCacheEntry->getZoneStringFormat(); 1956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCacheEntry::ZSFCacheEntry(const Locale &locale, ZoneStringFormat *zsf, ZSFCacheEntry *next) 1959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fLocale(locale), fZoneStringFormat(zsf), 1960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNext(next), fRefCount(1) 1961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 1962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCacheEntry::~ZSFCacheEntry () { 1965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete fZoneStringFormat; 1966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const ZoneStringFormat* 1969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCacheEntry::getZoneStringFormat(void) { 1970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (const ZoneStringFormat*)fZoneStringFormat; 1971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 1974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCacheEntry::delRef(void) { 1975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&gZSFCacheLock); 1976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --fRefCount; 1977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&gZSFCacheLock); 1978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCache::ZSFCache(int32_t capacity) 1981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): fCapacity(capacity), fFirst(NULL) { 1982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCache::~ZSFCache() { 1985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFCacheEntry *entry = fFirst; 1986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (entry) { 1987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFCacheEntry *next = entry->fNext; 1988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete entry; 1989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = next; 1990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SafeZoneStringFormatPtr* 1994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFCache::get(const Locale &locale, UErrorCode &status) { 1995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) SafeZoneStringFormatPtr *result = NULL; 1996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Search the cache entry list 1998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFCacheEntry *entry = NULL; 1999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFCacheEntry *next, *prev; 2000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&gZSFCacheLock); 2002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = fFirst; 2003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev = NULL; 2004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (entry) { 2005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) next = entry->fNext; 2006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry->fLocale == locale) { 2007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add reference count 2008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry->fRefCount++; 2009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // move the entry to the top 2011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry != fFirst) { 2012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev->fNext = next; 2013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry->fNext = fFirst; 2014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fFirst = entry; 2015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 2017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev = entry; 2019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = next; 2020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&gZSFCacheLock); 2022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Create a new ZoneStringFormat 2024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry == NULL) { 2025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZoneStringFormat *zsf = new ZoneStringFormat(locale, status); 2026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 2027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zsf; 2028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 2029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (zsf == NULL) { 2031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 2032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 2033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Now add the new entry 2036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&gZSFCacheLock); 2037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Make sure no other threads already created the one for the same locale 2038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = fFirst; 2039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev = NULL; 2040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (entry) { 2041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) next = entry->fNext; 2042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry->fLocale == locale) { 2043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add reference count 2044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry->fRefCount++; 2045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // move the entry to the top 2047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry != fFirst) { 2048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev->fNext = next; 2049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry->fNext = fFirst; 2050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fFirst = entry; 2051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 2053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev = entry; 2055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = next; 2056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry == NULL) { 2058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Add the new one to the top 2059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) next = fFirst; 2060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = new ZSFCacheEntry(locale, zsf, next); 2061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fFirst = entry; 2062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 2063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete zsf; 2064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&gZSFCacheLock); 2066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = new SafeZoneStringFormatPtr(entry); 2069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Now, delete unused cache entries beyond the capacity 2071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&gZSFCacheLock); 2072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = fFirst; 2073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev = NULL; 2074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t idx = 1; 2075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (entry) { 2076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) next = entry->fNext; 2077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (idx >= fCapacity && entry->fRefCount == 0) { 2078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (entry == fFirst) { 2079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fFirst = next; 2080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 2081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev->fNext = next; 2082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete entry; 2084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 2085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prev = entry; 2086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) entry = next; 2088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) idx++; 2089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&gZSFCacheLock); 2091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 2093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Zone String Formatter String Pool Implementation 2098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 2099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * String pool for (UChar *) strings. Avoids having repeated copies of the same string. 2100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 2101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t POOL_CHUNK_SIZE = 2000; 2103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct ZSFStringPoolChunk: public UMemory { 2104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFStringPoolChunk *fNext; // Ptr to next pool chunk 2105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t fLimit; // Index to start of unused area at end of fStrings 2106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar fStrings[POOL_CHUNK_SIZE]; // Strings array 2107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFStringPoolChunk(); 2108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 2109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFStringPoolChunk::ZSFStringPoolChunk() { 2111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fNext = NULL; 2112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fLimit = 0; 2113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFStringPool::ZSFStringPool(UErrorCode &status) { 2116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fChunks = NULL; 2117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fHash = NULL; 2118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 2119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 2120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fChunks = new ZSFStringPoolChunk; 2122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fChunks == NULL) { 2123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 2124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 2125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fHash = uhash_open(uhash_hashUChars /* keyHash */, 2128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_compareUChars /* keyComp */, 2129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_compareUChars /* valueComp */, 2130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 2131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 2132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 2133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ZSFStringPool::~ZSFStringPool() { 2138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fHash != NULL) { 2139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_close(fHash); 2140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fHash = NULL; 2141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (fChunks != NULL) { 2144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFStringPoolChunk *nextChunk = fChunks->fNext; 2145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete fChunks; 2146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fChunks = nextChunk; 2147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar EmptyString = 0; 2151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UChar *ZSFStringPool::get(const UChar *s, UErrorCode &status) { 2153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *pooledString; 2154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 2155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return &EmptyString; 2156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 2159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (pooledString != NULL) { 2160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return pooledString; 2161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length = u_strlen(s); 2164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remainingLength = POOL_CHUNK_SIZE - fChunks->fLimit; 2165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (remainingLength <= length) { 2166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_ASSERT(length < POOL_CHUNK_SIZE); 2167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (length >= POOL_CHUNK_SIZE) { 2168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_INTERNAL_PROGRAM_ERROR; 2169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return &EmptyString; 2170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ZSFStringPoolChunk *oldChunk = fChunks; 2172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fChunks = new ZSFStringPoolChunk; 2173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fChunks == NULL) { 2174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 2175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return &EmptyString; 2176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fChunks->fNext = oldChunk; 2178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *destString = &fChunks->fStrings[fChunks->fLimit]; 2181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_strcpy(destString, s); 2182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fChunks->fLimit += (length + 1); 2183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_put(fHash, destString, destString, &status); 2184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return destString; 2185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// 2189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ZSFStringPool::adopt() Put a string into the hash, but do not copy the string data 2190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// into the pool's storage. Used for strings from resource bundles, 2191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// which will perisist for the life of the zone string formatter, and 2192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// therefore can be used directly without copying. 2193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UChar *ZSFStringPool::adopt(const UChar * s, UErrorCode &status) { 2194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *pooledString; 2195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 2196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return &EmptyString; 2197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (s != NULL) { 2199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 2200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (pooledString == NULL) { 2201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *ncs = const_cast<UChar *>(s); 2202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_put(fHash, ncs, ncs, &status); 2203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 2205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return s; 2206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UChar *ZSFStringPool::get(const UnicodeString &s, UErrorCode &status) { 2210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString &nonConstStr = const_cast<UnicodeString &>(s); 2211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return this->get(nonConstStr.getTerminatedBuffer(), status); 2212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * freeze(). Close the hash table that maps to the pooled strings. 2216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * After freezing, the pool can not be searched or added to, 2217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * but all existing references to pooled strings remain valid. 2218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 2219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The main purpose is to recover the storage used for the hash. 2220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 2221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void ZSFStringPool::freeze() { 2222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uhash_close(fHash); 2223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fHash = NULL; 2224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 2225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END 2227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 2228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */ 2229