| Index: source/i18n/tzfmt.cpp
|
| diff --git a/source/i18n/tzfmt.cpp b/source/i18n/tzfmt.cpp
|
| index a2e8a5936a64ee83b8f20f8e60960222d737064a..6900fdf94ed41f3034b64feaac85d494e4543656 100644
|
| --- a/source/i18n/tzfmt.cpp
|
| +++ b/source/i18n/tzfmt.cpp
|
| @@ -1,6 +1,6 @@
|
| /*
|
| *******************************************************************************
|
| -* Copyright (C) 2011-2013, International Business Machines Corporation and
|
| +* Copyright (C) 2011-2014, International Business Machines Corporation and
|
| * others. All Rights Reserved.
|
| *******************************************************************************
|
| */
|
| @@ -308,7 +308,8 @@ U_CDECL_END
|
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneFormat)
|
|
|
| TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status)
|
| -: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL), fDefParseOptionFlags(0) {
|
| +: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL),
|
| + fDefParseOptionFlags(0), fTZDBTimeZoneNames(NULL) {
|
|
|
| for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
|
| fGMTOffsetPatternItems[i] = NULL;
|
| @@ -418,6 +419,7 @@ TimeZoneFormat::TimeZoneFormat(const TimeZoneFormat& other)
|
| TimeZoneFormat::~TimeZoneFormat() {
|
| delete fTimeZoneNames;
|
| delete fTimeZoneGenericNames;
|
| + delete fTZDBTimeZoneNames;
|
| for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
|
| delete fGMTOffsetPatternItems[i];
|
| }
|
| @@ -846,6 +848,8 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
| UErrorCode status = U_ZERO_ERROR;
|
| UnicodeString tzID;
|
|
|
| + UBool parseTZDBAbbrev = ((parseOptions & UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS) != 0);
|
| +
|
| // Try the specified style
|
| switch (style) {
|
| case UTZFMT_STYLE_LOCALIZED_GMT:
|
| @@ -956,6 +960,41 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
| return TimeZone::createTimeZone(tzID);
|
| }
|
| }
|
| +
|
| + if (parseTZDBAbbrev && style == UTZFMT_STYLE_SPECIFIC_SHORT) {
|
| + U_ASSERT((nameTypes & UTZNM_SHORT_STANDARD) != 0);
|
| + U_ASSERT((nameTypes & UTZNM_SHORT_DAYLIGHT) != 0);
|
| +
|
| + const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(status);
|
| + if (U_SUCCESS(status)) {
|
| + LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches(
|
| + tzdbTimeZoneNames->find(text, startIdx, nameTypes, status));
|
| + if (U_FAILURE(status)) {
|
| + pos.setErrorIndex(startIdx);
|
| + return NULL;
|
| + }
|
| + if (!tzdbNameMatches.isNull()) {
|
| + int32_t matchIdx = -1;
|
| + int32_t matchPos = -1;
|
| + for (int32_t i = 0; i < tzdbNameMatches->size(); i++) {
|
| + matchPos = startIdx + tzdbNameMatches->getMatchLengthAt(i);
|
| + if (matchPos > parsedPos) {
|
| + matchIdx = i;
|
| + parsedPos = matchPos;
|
| + }
|
| + }
|
| + if (matchIdx >= 0) {
|
| + if (timeType) {
|
| + *timeType = getTimeType(tzdbNameMatches->getNameTypeAt(matchIdx));
|
| + }
|
| + pos.setIndex(matchPos);
|
| + getTimeZoneID(tzdbNameMatches.getAlias(), matchIdx, tzID);
|
| + U_ASSERT(!tzID.isEmpty());
|
| + return TimeZone::createTimeZone(tzID);
|
| + }
|
| + }
|
| + }
|
| + }
|
| break;
|
| }
|
| case UTZFMT_STYLE_GENERIC_LONG:
|
| @@ -1168,6 +1207,34 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
| parsedOffset = UNKNOWN_OFFSET;
|
| }
|
| }
|
| + if (parseTZDBAbbrev && parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_SPECIFIC_SHORT]) == 0) {
|
| + const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(status);
|
| + if (U_SUCCESS(status)) {
|
| + LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches(
|
| + tzdbTimeZoneNames->find(text, startIdx, ALL_SIMPLE_NAME_TYPES, status));
|
| + if (U_FAILURE(status)) {
|
| + pos.setErrorIndex(startIdx);
|
| + return NULL;
|
| + }
|
| + int32_t tzdbNameMatchIdx = -1;
|
| + int32_t matchPos = -1;
|
| + if (!tzdbNameMatches.isNull()) {
|
| + for (int32_t i = 0; i < tzdbNameMatches->size(); i++) {
|
| + if (startIdx + tzdbNameMatches->getMatchLengthAt(i) > matchPos) {
|
| + tzdbNameMatchIdx = i;
|
| + matchPos = startIdx + tzdbNameMatches->getMatchLengthAt(i);
|
| + }
|
| + }
|
| + }
|
| + if (parsedPos < matchPos) {
|
| + U_ASSERT(tzdbNameMatchIdx >= 0);
|
| + parsedPos = matchPos;
|
| + getTimeZoneID(tzdbNameMatches.getAlias(), tzdbNameMatchIdx, parsedID);
|
| + parsedTimeType = getTimeType(tzdbNameMatches->getNameTypeAt(tzdbNameMatchIdx));
|
| + parsedOffset = UNKNOWN_OFFSET;
|
| + }
|
| + }
|
| + }
|
| // Try generic names
|
| if (parsedPos < maxPos) {
|
| int32_t genMatchLen = -1;
|
| @@ -1182,7 +1249,7 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
| return NULL;
|
| }
|
|
|
| - if (parsedPos < startIdx + genMatchLen) {
|
| + if (genMatchLen > 0 && parsedPos < startIdx + genMatchLen) {
|
| parsedPos = startIdx + genMatchLen;
|
| parsedID.setTo(tzID);
|
| parsedTimeType = tt;
|
| @@ -1313,6 +1380,27 @@ TimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const {
|
| return fTimeZoneGenericNames;
|
| }
|
|
|
| +const TZDBTimeZoneNames*
|
| +TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
|
| + if (U_FAILURE(status)) {
|
| + return NULL;
|
| + }
|
| +
|
| + umtx_lock(&gLock);
|
| + if (fTZDBTimeZoneNames == NULL) {
|
| + TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
|
| + if (tzdbNames == NULL) {
|
| + status = U_MEMORY_ALLOCATION_ERROR;
|
| + } else {
|
| + TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
|
| + nonConstThis->fTZDBTimeZoneNames = tzdbNames;
|
| + }
|
| + }
|
| + umtx_unlock(&gLock);
|
| +
|
| + return fTZDBTimeZoneNames;
|
| +}
|
| +
|
| UnicodeString&
|
| TimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name) const {
|
| UnicodeString location;
|
| @@ -2576,9 +2664,8 @@ TimeZoneFormat::getTimeType(UTimeZoneNameType nameType) {
|
| return UTZFMT_TIME_TYPE_DAYLIGHT;
|
|
|
| default:
|
| - U_ASSERT(FALSE);
|
| + return UTZFMT_TIME_TYPE_UNKNOWN;
|
| }
|
| - return UTZFMT_TIME_TYPE_UNKNOWN;
|
| }
|
|
|
| UnicodeString&
|
|
|