#include "unicode/uchar.h"
#include "unicode/udat.h"
#include "unicode/ustring.h"
+#include "unicode/utf16.h"
#include "tzgnames.h"
#include "cmemory.h"
#include "cstring.h"
#include "uvector.h"
#include "zonemeta.h"
#include "tznames_impl.h" // TextTrieMap
+#include "patternprops.h"
U_NAMESPACE_BEGIN
static TextTrieMap *gShortZoneIdTrie = NULL;
static icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;
-static UMutex gLock = U_MUTEX_INITIALIZER;
+static UMutex *gLock() {
+ static UMutex *m = STATIC_NEW(UMutex);
+ return m;
+}
U_CDECL_BEGIN
/**
case SECOND:
return (width == 2);
default:
- U_ASSERT(FALSE);
+ UPRV_UNREACHABLE;
}
return (width > 0);
}
}
const char* region = fLocale.getCountry();
- int32_t regionLen = uprv_strlen(region);
+ int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
if (regionLen == 0) {
char loc[ULOC_FULLNAME_CAPACITY];
uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status);
required = FIELDS_HMS;
break;
default:
- U_ASSERT(FALSE);
- break;
+ UPRV_UNREACHABLE;
}
UVector* patternItems = parseOffsetPattern(pattern, required, status);
if (tz != NULL) {
int32_t rawOffset, dstOffset;
tz->getOffset(date, FALSE, rawOffset, dstOffset, status);
- UChar buf[32];
+ UChar buf[ZONE_NAME_U16_MAX];
UnicodeString result(buf, 0, UPRV_LENGTHOF(buf));
formatOffsetLocalizedGMT(rawOffset + dstOffset, result, status);
if (U_SUCCESS(status)) {
break;
default:
- U_ASSERT(FALSE);
+ UPRV_UNREACHABLE;
}
int32_t len = 0;
return NULL;
}
- umtx_lock(&gLock);
+ umtx_lock(gLock());
if (fTimeZoneGenericNames == NULL) {
TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status);
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
return fTimeZoneGenericNames;
}
return NULL;
}
- umtx_lock(&gLock);
+ umtx_lock(gLock());
if (fTZDBTimeZoneNames == NULL) {
TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
if (tzdbNames == NULL) {
nonConstThis->fTZDBTimeZoneNames = tzdbNames;
}
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
return fTZDBTimeZoneNames;
}
UnicodeString&
TimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name) const {
- UChar locationBuf[64];
+ UChar locationBuf[ZONE_NAME_U16_MAX];
UnicodeString location(locationBuf, 0, UPRV_LENGTHOF(locationBuf));
const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz);
// but it should be parsed as 00:10:20.
int32_t tmpLen = 0;
int32_t tmpSign = 1;
- int32_t tmpH, tmpM, tmpS;
+ int32_t tmpH = 0;
+ int32_t tmpM = 0;
+ int32_t tmpS = 0;
for (int32_t patidx = 0; PARSE_GMT_OFFSET_TYPES[patidx] >= 0; patidx++) {
int32_t gmtPatType = PARSE_GMT_OFFSET_TYPES[patidx];
if (fieldType == GMTOffsetField::TEXT) {
const UChar* patStr = field->getPatternText();
len = u_strlen(patStr);
+ if (i == 0) {
+ // When TimeZoneFormat parse() is called from SimpleDateFormat,
+ // leading space characters might be truncated. If the first pattern text
+ // starts with such character (e.g. Bidi control), then we need to
+ // skip the leading space charcters.
+ if (idx < text.length() && !PatternProps::isWhiteSpace(text.char32At(idx))) {
+ while (len > 0) {
+ UChar32 ch;
+ int32_t chLen;
+ U16_GET(patStr, 0, 0, len, ch)
+ if (PatternProps::isWhiteSpace(ch)) {
+ chLen = U16_LENGTH(ch);
+ len -= chLen;
+ patStr += chLen;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ }
if (text.caseCompare(idx, len, patStr, 0) != 0) {
failed = TRUE;
break;
isPrevQuote = TRUE;
if (itemType != GMTOffsetField::TEXT) {
if (GMTOffsetField::isValid(itemType, itemLength)) {
- GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, (uint8_t)itemLength, status);
+ GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
result->addElement(fld, status);
if (U_FAILURE(status)) {
break;
}
} else {
if (GMTOffsetField::isValid(itemType, itemLength)) {
- GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, itemLength, status);
+ GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
result->addElement(fld, status);
if (U_FAILURE(status)) {
break;
// a string literal
if (itemType != GMTOffsetField::TEXT) {
if (GMTOffsetField::isValid(itemType, itemLength)) {
- GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, itemLength, status);
+ GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
result->addElement(fld, status);
if (U_FAILURE(status)) {
break;
}
} else {
if (GMTOffsetField::isValid(itemType, itemLength)) {
- GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, itemLength, status);
+ GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
result->addElement(fld, status);
} else {
status = U_ILLEGAL_ARGUMENT_ERROR;
UVector *items = fGMTOffsetPatternItems[type];
for (int32_t i = 0; i < items->size(); i++) {
const GMTOffsetField* item = (GMTOffsetField*)items->elementAt(i);
- GMTOffsetField::FieldType type = item->getType();
- if (type != GMTOffsetField::TEXT) {
+ GMTOffsetField::FieldType fieldType = item->getType();
+ if (fieldType != GMTOffsetField::TEXT) {
if (afterH) {
fAbuttingOffsetHoursAndMinutes = TRUE;
break;
- } else if (type == GMTOffsetField::HOUR) {
+ } else if (fieldType == GMTOffsetField::HOUR) {
afterH = TRUE;
}
} else if (afterH) {
}
StringEnumeration *tzenum = TimeZone::createEnumeration();
const UnicodeString *id;
- while ((id = tzenum->snext(status))) {
+ while ((id = tzenum->snext(status)) != NULL) {
const UChar* uid = ZoneMeta::findTimeZoneID(*id);
if (uid) {
gZoneIdTrie->put(uid, const_cast<UChar *>(uid), status);
status = U_MEMORY_ALLOCATION_ERROR;
} else {
const UnicodeString *id;
- while ((id = tzenum->snext(status))) {
+ while ((id = tzenum->snext(status)) != NULL) {
const UChar* uID = ZoneMeta::findTimeZoneID(*id);
const UChar* shortID = ZoneMeta::getShortID(*id);
if (shortID && uID) {