Index: source/i18n/dtitvinf.cpp |
diff --git a/source/i18n/dtitvinf.cpp b/source/i18n/dtitvinf.cpp |
index 74f84882876d9757cd9de57c5171428cd11d7a7c..07129db928b31a519a66d9d4f47151210b50af06 100644 |
--- a/source/i18n/dtitvinf.cpp |
+++ b/source/i18n/dtitvinf.cpp |
@@ -1,9 +1,11 @@ |
+// Copyright (C) 2016 and later: Unicode, Inc. and others. |
+// License & terms of use: http://www.unicode.org/copyright.html |
/******************************************************************************* |
-* Copyright (C) 2008-2015, International Business Machines Corporation and |
+* Copyright (C) 2008-2016, International Business Machines Corporation and |
* others. All Rights Reserved. |
******************************************************************************* |
* |
-* File DTITVINF.CPP |
+* File DTITVINF.CPP |
* |
******************************************************************************* |
*/ |
@@ -17,15 +19,17 @@ |
//#define DTITVINF_DEBUG 1 |
-#ifdef DTITVINF_DEBUG |
+#ifdef DTITVINF_DEBUG |
#include <iostream> |
#endif |
+#include "cmemory.h" |
#include "cstring.h" |
#include "unicode/msgfmt.h" |
#include "unicode/uloc.h" |
#include "unicode/ures.h" |
#include "dtitv_impl.h" |
+#include "charstr.h" |
#include "hash.h" |
#include "gregoimp.h" |
#include "uresimp.h" |
@@ -37,7 +41,7 @@ |
U_NAMESPACE_BEGIN |
-#ifdef DTITVINF_DEBUG |
+#ifdef DTITVINF_DEBUG |
#define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; } |
#endif |
@@ -56,9 +60,7 @@ static const UChar gSecondPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ONE, RIGHT_CURL |
// default fall-back |
static const UChar gDefaultFallbackPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, EN_DASH, SPACE, LEFT_CURLY_BRACKET, DIGIT_ONE, RIGHT_CURLY_BRACKET, 0}; |
- |
- |
-DateIntervalInfo::DateIntervalInfo(UErrorCode& status) |
+DateIntervalInfo::DateIntervalInfo(UErrorCode& status) |
: fFallbackIntervalPattern(gDefaultFallbackPattern), |
fFirstDateInPtnIsLaterDate(false), |
fIntervalPatterns(NULL) |
@@ -83,7 +85,7 @@ DateIntervalInfo::setIntervalPattern(const UnicodeString& skeleton, |
UCalendarDateFields lrgDiffCalUnit, |
const UnicodeString& intervalPattern, |
UErrorCode& status) { |
- |
+ |
if ( lrgDiffCalUnit == UCAL_HOUR_OF_DAY ) { |
setIntervalPatternInternally(skeleton, UCAL_AM_PM, intervalPattern, status); |
setIntervalPatternInternally(skeleton, UCAL_HOUR, intervalPattern, status); |
@@ -103,15 +105,15 @@ DateIntervalInfo::setFallbackIntervalPattern( |
if ( U_FAILURE(status) ) { |
return; |
} |
- int32_t firstPatternIndex = fallbackPattern.indexOf(gFirstPattern, |
- sizeof(gFirstPattern)/sizeof(gFirstPattern[0]), 0); |
- int32_t secondPatternIndex = fallbackPattern.indexOf(gSecondPattern, |
- sizeof(gSecondPattern)/sizeof(gSecondPattern[0]), 0); |
+ int32_t firstPatternIndex = fallbackPattern.indexOf(gFirstPattern, |
+ UPRV_LENGTHOF(gFirstPattern), 0); |
+ int32_t secondPatternIndex = fallbackPattern.indexOf(gSecondPattern, |
+ UPRV_LENGTHOF(gSecondPattern), 0); |
if ( firstPatternIndex == -1 || secondPatternIndex == -1 ) { |
status = U_ILLEGAL_ARGUMENT_ERROR; |
return; |
} |
- if ( firstPatternIndex > secondPatternIndex ) { |
+ if ( firstPatternIndex > secondPatternIndex ) { |
fFirstDateInPtnIsLaterDate = true; |
} |
fFallbackIntervalPattern = fallbackPattern; |
@@ -125,7 +127,7 @@ DateIntervalInfo::DateIntervalInfo(const DateIntervalInfo& dtitvinf) |
{ |
*this = dtitvinf; |
} |
- |
+ |
DateIntervalInfo& |
@@ -133,14 +135,14 @@ DateIntervalInfo::operator=(const DateIntervalInfo& dtitvinf) { |
if ( this == &dtitvinf ) { |
return *this; |
} |
- |
+ |
UErrorCode status = U_ZERO_ERROR; |
deleteHash(fIntervalPatterns); |
fIntervalPatterns = initHash(status); |
copyHash(dtitvinf.fIntervalPatterns, fIntervalPatterns, status); |
if ( U_FAILURE(status) ) { |
return *this; |
- } |
+ } |
fFallbackIntervalPattern = dtitvinf.fFallbackIntervalPattern; |
fFirstDateInPtnIsLaterDate = dtitvinf.fFirstDateInPtnIsLaterDate; |
@@ -162,7 +164,7 @@ DateIntervalInfo::~DateIntervalInfo() { |
UBool |
DateIntervalInfo::operator==(const DateIntervalInfo& other) const { |
- UBool equal = ( |
+ UBool equal = ( |
fFallbackIntervalPattern == other.fFallbackIntervalPattern && |
fFirstDateInPtnIsLaterDate == other.fFirstDateInPtnIsLaterDate ); |
@@ -182,7 +184,7 @@ DateIntervalInfo::getIntervalPattern(const UnicodeString& skeleton, |
if ( U_FAILURE(status) ) { |
return result; |
} |
- |
+ |
const UnicodeString* patternsOfOneSkeleton = (UnicodeString*) fIntervalPatterns->get(skeleton); |
if ( patternsOfOneSkeleton != NULL ) { |
IntervalPatternIndex index = calendarFieldToIntervalIndex(field, status); |
@@ -212,158 +214,263 @@ DateIntervalInfo::getFallbackIntervalPattern(UnicodeString& result) const { |
#define ULOC_LOCALE_IDENTIFIER_CAPACITY (ULOC_FULLNAME_CAPACITY + 1 + ULOC_KEYWORD_AND_VALUES_CAPACITY) |
-void |
-DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& err) |
+ |
+static const int32_t PATH_PREFIX_LENGTH = 17; |
+static const UChar PATH_PREFIX[] = {SOLIDUS, CAP_L, CAP_O, CAP_C, CAP_A, CAP_L, CAP_E, SOLIDUS, |
+ LOW_C, LOW_A, LOW_L, LOW_E, LOW_N, LOW_D, LOW_A, LOW_R, SOLIDUS}; |
+static const int32_t PATH_SUFFIX_LENGTH = 16; |
+static const UChar PATH_SUFFIX[] = {SOLIDUS, LOW_I, LOW_N, LOW_T, LOW_E, LOW_R, LOW_V, LOW_A, |
+ LOW_L, CAP_F, LOW_O, LOW_R, LOW_M, LOW_A, LOW_T, LOW_S}; |
+ |
+/** |
+ * Sink for enumerating all of the date interval skeletons. |
+ */ |
+struct DateIntervalInfo::DateIntervalSink : public ResourceSink { |
+ |
+ // Output data |
+ DateIntervalInfo &dateIntervalInfo; |
+ |
+ // Next calendar type |
+ UnicodeString nextCalendarType; |
+ |
+ DateIntervalSink(DateIntervalInfo &diInfo, const char *currentCalendarType) |
+ : dateIntervalInfo(diInfo), nextCalendarType(currentCalendarType, -1, US_INV) { } |
+ virtual ~DateIntervalSink(); |
+ |
+ virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &errorCode) { |
+ if (U_FAILURE(errorCode)) { return; } |
+ |
+ // Iterate over all the calendar entries and only pick the 'intervalFormats' table. |
+ ResourceTable dateIntervalData = value.getTable(errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ for (int32_t i = 0; dateIntervalData.getKeyAndValue(i, key, value); i++) { |
+ if (uprv_strcmp(key, gIntervalDateTimePatternTag) != 0) { |
+ continue; |
+ } |
+ |
+ // Handle aliases and tables. Ignore the rest. |
+ if (value.getType() == URES_ALIAS) { |
+ // Get the calendar type for the alias path. |
+ const UnicodeString &aliasPath = value.getAliasUnicodeString(errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ |
+ nextCalendarType.remove(); |
+ getCalendarTypeFromPath(aliasPath, nextCalendarType, errorCode); |
+ |
+ if (U_FAILURE(errorCode)) { |
+ resetNextCalendarType(); |
+ } |
+ break; |
+ |
+ } else if (value.getType() == URES_TABLE) { |
+ // Iterate over all the skeletons in the 'intervalFormat' table. |
+ ResourceTable skeletonData = value.getTable(errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ for (int32_t j = 0; skeletonData.getKeyAndValue(j, key, value); j++) { |
+ if (value.getType() == URES_TABLE) { |
+ // Process the skeleton |
+ processSkeletonTable(key, value, errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ } |
+ } |
+ break; |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Processes the patterns for a skeleton table |
+ */ |
+ void processSkeletonTable(const char *key, ResourceValue &value, UErrorCode &errorCode) { |
+ if (U_FAILURE(errorCode)) { return; } |
+ |
+ // Iterate over all the patterns in the current skeleton table |
+ const char *currentSkeleton = key; |
+ ResourceTable patternData = value.getTable(errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ for (int32_t k = 0; patternData.getKeyAndValue(k, key, value); k++) { |
+ if (value.getType() == URES_STRING) { |
+ // Process the key |
+ UCalendarDateFields calendarField = validateAndProcessPatternLetter(key); |
+ |
+ // If the calendar field has a valid value |
+ if (calendarField < UCAL_FIELD_COUNT) { |
+ // Set the interval pattern |
+ setIntervalPatternIfAbsent(currentSkeleton, calendarField, value, errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ } |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Extracts the calendar type from the path. |
+ */ |
+ static void getCalendarTypeFromPath(const UnicodeString &path, UnicodeString &calendarType, |
+ UErrorCode &errorCode) { |
+ if (U_FAILURE(errorCode)) { return; } |
+ |
+ if (!path.startsWith(PATH_PREFIX, PATH_PREFIX_LENGTH) || !path.endsWith(PATH_SUFFIX, PATH_SUFFIX_LENGTH)) { |
+ errorCode = U_INVALID_FORMAT_ERROR; |
+ return; |
+ } |
+ |
+ path.extractBetween(PATH_PREFIX_LENGTH, path.length() - PATH_SUFFIX_LENGTH, calendarType); |
+ } |
+ |
+ /** |
+ * Validates and processes the pattern letter |
+ */ |
+ UCalendarDateFields validateAndProcessPatternLetter(const char *patternLetter) { |
+ // Check that patternLetter is just one letter |
+ char c0; |
+ if ((c0 = patternLetter[0]) != 0 && patternLetter[1] == 0) { |
+ // Check that the pattern letter is accepted |
+ if (c0 == 'y') { |
+ return UCAL_YEAR; |
+ } else if (c0 == 'M') { |
+ return UCAL_MONTH; |
+ } else if (c0 == 'd') { |
+ return UCAL_DATE; |
+ } else if (c0 == 'a') { |
+ return UCAL_AM_PM; |
+ } else if (c0 == 'h' || c0 == 'H') { |
+ return UCAL_HOUR; |
+ } else if (c0 == 'm') { |
+ return UCAL_MINUTE; |
+ }// TODO(ticket:12190): Why icu4c doesn't accept the calendar field "s" but icu4j does? |
+ } |
+ return UCAL_FIELD_COUNT; |
+ } |
+ |
+ /** |
+ * Stores the interval pattern for the current skeleton in the internal data structure |
+ * if it's not present. |
+ */ |
+ void setIntervalPatternIfAbsent(const char *currentSkeleton, UCalendarDateFields lrgDiffCalUnit, |
+ const ResourceValue &value, UErrorCode &errorCode) { |
+ // Check if the pattern has already been stored on the data structure |
+ IntervalPatternIndex index = |
+ dateIntervalInfo.calendarFieldToIntervalIndex(lrgDiffCalUnit, errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ |
+ UnicodeString skeleton(currentSkeleton, -1, US_INV); |
+ UnicodeString* patternsOfOneSkeleton = |
+ (UnicodeString*)(dateIntervalInfo.fIntervalPatterns->get(skeleton)); |
+ |
+ if (patternsOfOneSkeleton == NULL || patternsOfOneSkeleton[index].isEmpty()) { |
+ UnicodeString pattern = value.getUnicodeString(errorCode); |
+ dateIntervalInfo.setIntervalPatternInternally(skeleton, lrgDiffCalUnit, |
+ pattern, errorCode); |
+ } |
+ } |
+ |
+ const UnicodeString &getNextCalendarType() { |
+ return nextCalendarType; |
+ } |
+ |
+ void resetNextCalendarType() { |
+ nextCalendarType.setToBogus(); |
+ } |
+}; |
+ |
+// Virtual destructors must be defined out of line. |
+DateIntervalInfo::DateIntervalSink::~DateIntervalSink() {} |
+ |
+ |
+ |
+void |
+DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) |
{ |
- fIntervalPatterns = initHash(err); |
- if ( U_FAILURE(err) ) { |
- return; |
- } |
- const char *locName = locale.getName(); |
- char parentLocale[ULOC_FULLNAME_CAPACITY]; |
- uprv_strcpy(parentLocale, locName); |
- UErrorCode status = U_ZERO_ERROR; |
- Hashtable skeletonKeyPairs(FALSE, status); |
- if ( U_FAILURE(status) ) { |
+ fIntervalPatterns = initHash(status); |
+ if (U_FAILURE(status)) { |
return; |
- } |
- |
- // determine calendar type |
- const char * calendarTypeToUse = gGregorianTag; // initial default |
- char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well |
- char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; |
- // obtain a locale that always has the calendar key value that should be used |
- (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL, |
+ } |
+ const char *locName = locale.getName(); |
+ |
+ // Get the correct calendar type |
+ const char * calendarTypeToUse = gGregorianTag; // initial default |
+ char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well |
+ char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; |
+ // obtain a locale that always has the calendar key value that should be used |
+ (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL, |
"calendar", "calendar", locName, NULL, FALSE, &status); |
- localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination |
- // now get the calendar key value from that locale |
- int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, ULOC_KEYWORDS_CAPACITY, &status); |
- if (U_SUCCESS(status) && calendarTypeLen < ULOC_KEYWORDS_CAPACITY) { |
- calendarTypeToUse = calendarType; |
- } |
- status = U_ZERO_ERROR; |
- |
- do { |
- UResourceBundle *rb, *calBundle, *calTypeBundle, *itvDtPtnResource; |
- rb = ures_open(NULL, parentLocale, &status); |
- if ( U_FAILURE(status) ) { |
- break; |
+ localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination |
+ // now get the calendar key value from that locale |
+ int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, |
+ ULOC_KEYWORDS_CAPACITY, &status); |
+ if (U_SUCCESS(status) && calendarTypeLen < ULOC_KEYWORDS_CAPACITY) { |
+ calendarTypeToUse = calendarType; |
+ } |
+ status = U_ZERO_ERROR; |
+ |
+ // Instantiate the resource bundles |
+ UResourceBundle *rb, *calBundle; |
+ rb = ures_open(NULL, locName, &status); |
+ if (U_FAILURE(status)) { |
+ return; |
} |
- calBundle = ures_getByKey(rb, gCalendarTag, NULL, &status); |
- calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &status); |
- itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle, |
- gIntervalDateTimePatternTag, NULL, &status); |
+ calBundle = ures_getByKeyWithFallback(rb, gCalendarTag, NULL, &status); |
- if ( U_SUCCESS(status) ) { |
- // look for fallback first, since it establishes the default order |
+ |
+ if (U_SUCCESS(status)) { |
+ UResourceBundle *calTypeBundle, *itvDtPtnResource; |
+ |
+ // Get the fallback pattern |
const UChar* resStr; |
int32_t resStrLen = 0; |
- resStr = ures_getStringByKeyWithFallback(itvDtPtnResource, |
- gFallbackPatternTag, |
- &resStrLen, &status); |
+ calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, NULL, &status); |
+ itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle, |
+ gIntervalDateTimePatternTag, NULL, &status); |
+ resStr = ures_getStringByKeyWithFallback(itvDtPtnResource, gFallbackPatternTag, |
+ &resStrLen, &status); |
if ( U_SUCCESS(status) ) { |
UnicodeString pattern = UnicodeString(TRUE, resStr, resStrLen); |
setFallbackIntervalPattern(pattern, status); |
} |
+ ures_close(itvDtPtnResource); |
+ ures_close(calTypeBundle); |
- int32_t size = ures_getSize(itvDtPtnResource); |
- int32_t index; |
- for ( index = 0; index < size; ++index ) { |
- LocalUResourceBundlePointer oneRes(ures_getByIndex(itvDtPtnResource, index, |
- NULL, &status)); |
- if ( U_SUCCESS(status) ) { |
- const char* skeleton = ures_getKey(oneRes.getAlias()); |
- if (skeleton == NULL) { |
- continue; |
- } |
- UnicodeString skeletonUniStr(skeleton, -1, US_INV); |
- if ( uprv_strcmp(skeleton, gFallbackPatternTag) == 0 ) { |
- continue; // fallback |
- } |
- LocalUResourceBundlePointer intervalPatterns(ures_getByKey( |
- itvDtPtnResource, skeleton, NULL, &status)); |
+ // Instantiate the sink |
+ DateIntervalSink sink(*this, calendarTypeToUse); |
+ const UnicodeString &calendarTypeToUseUString = sink.getNextCalendarType(); |
+ |
+ // Already loaded calendar types |
+ Hashtable loadedCalendarTypes(FALSE, status); |
- if ( U_FAILURE(status) ) { |
+ if (U_SUCCESS(status)) { |
+ while (!calendarTypeToUseUString.isBogus()) { |
+ // Set an error when a loop is detected |
+ if (loadedCalendarTypes.geti(calendarTypeToUseUString) == 1) { |
+ status = U_INVALID_FORMAT_ERROR; |
break; |
} |
- if ( intervalPatterns == NULL ) { |
- continue; |
- } |
- const char* key; |
- int32_t ptnNum = ures_getSize(intervalPatterns.getAlias()); |
- int32_t ptnIndex; |
- for ( ptnIndex = 0; ptnIndex < ptnNum; ++ptnIndex ) { |
- UnicodeString pattern = |
- ures_getNextUnicodeString(intervalPatterns.getAlias(), &key, &status); |
- if ( U_FAILURE(status) ) { |
- break; |
- } |
- UnicodeString keyUniStr(key, -1, US_INV); |
- UnicodeString skeletonKeyPair(skeletonUniStr + keyUniStr); |
- if ( skeletonKeyPairs.geti(skeletonKeyPair) == 1 ) { |
- continue; |
- } |
- skeletonKeyPairs.puti(skeletonKeyPair, 1, status); |
- |
- UCalendarDateFields calendarField = UCAL_FIELD_COUNT; |
- if ( !uprv_strcmp(key, "y") ) { |
- calendarField = UCAL_YEAR; |
- } else if ( !uprv_strcmp(key, "M") ) { |
- calendarField = UCAL_MONTH; |
- } else if ( !uprv_strcmp(key, "d") ) { |
- calendarField = UCAL_DATE; |
- } else if ( !uprv_strcmp(key, "a") ) { |
- calendarField = UCAL_AM_PM; |
- } else if ( !uprv_strcmp(key, "h") || !uprv_strcmp(key, "H") ) { |
- calendarField = UCAL_HOUR; |
- } else if ( !uprv_strcmp(key, "m") ) { |
- calendarField = UCAL_MINUTE; |
- } |
- if ( calendarField != UCAL_FIELD_COUNT ) { |
- setIntervalPatternInternally(skeletonUniStr, calendarField, pattern,status); |
- } |
- } |
+ // Register the calendar type to avoid loops |
+ loadedCalendarTypes.puti(calendarTypeToUseUString, 1, status); |
+ if (U_FAILURE(status)) { break; } |
+ |
+ // Get the calendar string |
+ CharString calTypeBuffer; |
+ calTypeBuffer.appendInvariantChars(calendarTypeToUseUString, status); |
+ if (U_FAILURE(status)) { break; } |
+ const char *calType = calTypeBuffer.data(); |
+ |
+ // Reset the next calendar type to load. |
+ sink.resetNextCalendarType(); |
+ |
+ // Get all resources for this calendar type |
+ ures_getAllItemsWithFallback(calBundle, calType, sink, status); |
} |
} |
} |
- ures_close(itvDtPtnResource); |
- ures_close(calTypeBundle); |
- ures_close(calBundle); |
- status = U_ZERO_ERROR; |
- // Find the name of the appropriate parent locale (from %%Parent if present, else |
- // uloc_getParent on the actual locale name) |
- // (It would be nice to have a ures function that did this...) |
- int32_t locNameLen; |
- const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &locNameLen, &status); |
- if (U_SUCCESS(status) && status != U_USING_FALLBACK_WARNING && locNameLen < ULOC_FULLNAME_CAPACITY) { |
- u_UCharsToChars(parentUName, parentLocale, locNameLen + 1); |
- } else { |
- status = U_ZERO_ERROR; |
- // Get the actual name of the current locale being used |
- const char *curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &status); |
- if ( U_FAILURE(status) ) { |
- curLocaleName = parentLocale; |
- status = U_ZERO_ERROR; |
- } |
- uloc_getParent(curLocaleName, parentLocale, ULOC_FULLNAME_CAPACITY, &status); |
- if (U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) { |
- parentLocale[0] = 0; // just fallback to root, will cause us to stop |
- status = U_ZERO_ERROR; |
- } |
- } |
- // Now we can close the current locale bundle |
+ // Close the opened resource bundles |
+ ures_close(calBundle); |
ures_close(rb); |
- // If the new current locale is root, then stop |
- // (unlike for DateTimePatternGenerator, DateIntervalFormat does not go all the way up |
- // to root to find additional data for non-root locales) |
- } while ( parentLocale[0] != 0 && uprv_strcmp(parentLocale,"root")!=0 ); |
} |
- |
- |
void |
DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, |
UCalendarDateFields lrgDiffCalUnit, |
@@ -379,7 +486,7 @@ DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, |
patternsOfOneSkeleton = new UnicodeString[kIPI_MAX_INDEX]; |
emptyHash = true; |
} |
- |
+ |
patternsOfOneSkeleton[index] = intervalPattern; |
if ( emptyHash == TRUE ) { |
fIntervalPatterns->put(skeleton, patternsOfOneSkeleton, status); |
@@ -388,21 +495,21 @@ DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, |
-void |
-DateIntervalInfo::parseSkeleton(const UnicodeString& skeleton, |
+void |
+DateIntervalInfo::parseSkeleton(const UnicodeString& skeleton, |
int32_t* skeletonFieldWidth) { |
const int8_t PATTERN_CHAR_BASE = 0x41; |
int32_t i; |
for ( i = 0; i < skeleton.length(); ++i ) { |
// it is an ASCII char in skeleton |
- int8_t ch = (int8_t)skeleton.charAt(i); |
+ int8_t ch = (int8_t)skeleton.charAt(i); |
++skeletonFieldWidth[ch - PATTERN_CHAR_BASE]; |
} |
} |
-UBool |
+UBool |
DateIntervalInfo::stringNumeric(int32_t fieldWidth, int32_t anotherFieldWidth, |
char patternLetter) { |
if ( patternLetter == 'M' ) { |
@@ -416,7 +523,7 @@ DateIntervalInfo::stringNumeric(int32_t fieldWidth, int32_t anotherFieldWidth, |
-const UnicodeString* |
+const UnicodeString* |
DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, |
int8_t& bestMatchDistanceInfo) const { |
#ifdef DTITVINF_DEBUG |
@@ -463,7 +570,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, |
// resource bundle only have time skeletons ending with 'v', |
// but not for time skeletons ending with 'z'. |
UBool replaceZWithV = false; |
- const UnicodeString* inputSkeleton = &skeleton; |
+ const UnicodeString* inputSkeleton = &skeleton; |
UnicodeString copySkeleton; |
if ( skeleton.indexOf(CHAR_Z) != -1 ) { |
copySkeleton = skeleton; |
@@ -481,7 +588,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, |
// 2 means only z/v differs |
// -1 means having different field. |
bestMatchDistanceInfo = 0; |
- int8_t fieldLength = sizeof(skeletonFieldWidth)/sizeof(skeletonFieldWidth[0]); |
+ int8_t fieldLength = UPRV_LENGTHOF(skeletonFieldWidth); |
int32_t pos = UHASH_FIRST; |
const UHashElement* elem = NULL; |
@@ -497,7 +604,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, |
// clear skeleton field width |
int8_t i; |
for ( i = 0; i < fieldLength; ++i ) { |
- skeletonFieldWidth[i] = 0; |
+ skeletonFieldWidth[i] = 0; |
} |
parseSkeleton(*skeleton, skeletonFieldWidth); |
// calculate distance |
@@ -515,12 +622,12 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, |
} else if ( fieldWidth == 0 ) { |
fieldDifference = -1; |
distance += DIFFERENT_FIELD; |
- } else if (stringNumeric(inputFieldWidth, fieldWidth, |
+ } else if (stringNumeric(inputFieldWidth, fieldWidth, |
(char)(i+BASE) ) ) { |
distance += STRING_NUMERIC_DIFFERENCE; |
} else { |
- distance += (inputFieldWidth > fieldWidth) ? |
- (inputFieldWidth - fieldWidth) : |
+ distance += (inputFieldWidth > fieldWidth) ? |
+ (inputFieldWidth - fieldWidth) : |
(fieldWidth - inputFieldWidth); |
} |
} |
@@ -543,7 +650,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, |
DateIntervalInfo::IntervalPatternIndex |
-DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, |
+DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, |
UErrorCode& status) { |
if ( U_FAILURE(status) ) { |
return kIPI_MAX_INDEX; |
@@ -586,7 +693,7 @@ DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, |
void |
-DateIntervalInfo::deleteHash(Hashtable* hTable) |
+DateIntervalInfo::deleteHash(Hashtable* hTable) |
{ |
if ( hTable == NULL ) { |
return; |
@@ -602,7 +709,7 @@ DateIntervalInfo::deleteHash(Hashtable* hTable) |
} |
-U_CDECL_BEGIN |
+U_CDECL_BEGIN |
/** |
* set hash table value comparator |
@@ -613,7 +720,7 @@ U_CDECL_BEGIN |
*/ |
static UBool U_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2); |
-static UBool |
+static UBool |
U_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2) { |
const UnicodeString* pattern1 = (UnicodeString*)val1.pointer; |
const UnicodeString* pattern2 = (UnicodeString*)val2.pointer; |
@@ -639,7 +746,7 @@ DateIntervalInfo::initHash(UErrorCode& status) { |
return NULL; |
} |
if ( U_FAILURE(status) ) { |
- delete hTable; |
+ delete hTable; |
return NULL; |
} |
hTable->setValueComparator(dtitvinfHashTableValueComparator); |