/*
*******************************************************************************
-* Copyright (C) 2007-2009, International Business Machines Corporation and
+* Copyright (C) 2007-2011, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
/**
- * If we are on EBCDIC, use an iterator which will
+ * If we are on EBCDIC, use an iterator which will
* traverse the bundles in ASCII order.
*/
#define U_USE_ASCII_BUNDLE_ITERATOR
/* Must be C linkage to pass function pointer to the sort function */
-extern "C" static int32_t U_CALLCONV
+#if !defined (OS390) && !defined (OS400)
+extern "C"
+#endif
+static int32_t U_CALLCONV
ures_a_codepointSort(const void *context, const void *left, const void *right) {
//CompareContext *cmp=(CompareContext *)context;
return u_strcmp(((const UResAEntry *)left)->key,
// class DateTimePatternGenerator
// *****************************************************************************
static const UChar Canonical_Items[] = {
- // GyQMwWedDFHmsSv
- CAP_G, LOW_Y, CAP_Q, CAP_M, LOW_W, CAP_W, LOW_E, LOW_D, CAP_D, CAP_F,
+ // GyQMwWEdDFHmsSv
+ CAP_G, LOW_Y, CAP_Q, CAP_M, LOW_W, CAP_W, CAP_E, LOW_D, CAP_D, CAP_F,
CAP_H, LOW_M, LOW_S, CAP_S, LOW_V, 0
};
{CAP_Q, UDATPG_QUARTER_FIELD, DT_NUMERIC, 1, 2},
{CAP_Q, UDATPG_QUARTER_FIELD, DT_SHORT, 3, 0},
{CAP_Q, UDATPG_QUARTER_FIELD, DT_LONG, 4, 0},
+ {LOW_Q, UDATPG_QUARTER_FIELD, DT_NUMERIC + DT_DELTA, 1, 2},
+ {LOW_Q, UDATPG_QUARTER_FIELD, DT_SHORT + DT_DELTA, 3, 0},
+ {LOW_Q, UDATPG_QUARTER_FIELD, DT_LONG + DT_DELTA, 4, 0},
{CAP_M, UDATPG_MONTH_FIELD, DT_NUMERIC, 1, 2},
{CAP_M, UDATPG_MONTH_FIELD, DT_SHORT, 3, 0},
{CAP_M, UDATPG_MONTH_FIELD, DT_LONG, 4, 0},
{CAP_L, UDATPG_MONTH_FIELD, DT_NARROW - DT_DELTA, 5, 0},
{LOW_W, UDATPG_WEEK_OF_YEAR_FIELD, DT_NUMERIC, 1, 2},
{CAP_W, UDATPG_WEEK_OF_MONTH_FIELD, DT_NUMERIC + DT_DELTA, 1, 0},
- {LOW_E, UDATPG_WEEKDAY_FIELD, DT_NUMERIC + DT_DELTA, 1, 2},
- {LOW_E, UDATPG_WEEKDAY_FIELD, DT_SHORT - DT_DELTA, 3, 0},
- {LOW_E, UDATPG_WEEKDAY_FIELD, DT_LONG - DT_DELTA, 4, 0},
- {LOW_E, UDATPG_WEEKDAY_FIELD, DT_NARROW - DT_DELTA, 5, 0},
{CAP_E, UDATPG_WEEKDAY_FIELD, DT_SHORT, 1, 3},
{CAP_E, UDATPG_WEEKDAY_FIELD, DT_LONG, 4, 0},
{CAP_E, UDATPG_WEEKDAY_FIELD, DT_NARROW, 5, 0},
{LOW_C, UDATPG_WEEKDAY_FIELD, DT_SHORT - 2*DT_DELTA, 3, 0},
{LOW_C, UDATPG_WEEKDAY_FIELD, DT_LONG - 2*DT_DELTA, 4, 0},
{LOW_C, UDATPG_WEEKDAY_FIELD, DT_NARROW - 2*DT_DELTA, 5, 0},
+ {LOW_E, UDATPG_WEEKDAY_FIELD, DT_NUMERIC + DT_DELTA, 1, 2}, // LOW_E is currently not used in CLDR data, should not be canonical
+ {LOW_E, UDATPG_WEEKDAY_FIELD, DT_SHORT - DT_DELTA, 3, 0},
+ {LOW_E, UDATPG_WEEKDAY_FIELD, DT_LONG - DT_DELTA, 4, 0},
+ {LOW_E, UDATPG_WEEKDAY_FIELD, DT_NARROW - DT_DELTA, 5, 0},
{LOW_D, UDATPG_DAY_FIELD, DT_NUMERIC, 1, 2},
{CAP_D, UDATPG_DAY_OF_YEAR_FIELD, DT_NUMERIC + DT_DELTA, 1, 3},
{CAP_F, UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD, DT_NUMERIC + 2*DT_DELTA, 1, 0},
{LOW_Z, UDATPG_ZONE_FIELD, DT_LONG, 4, 0},
{CAP_Z, UDATPG_ZONE_FIELD, DT_SHORT - DT_DELTA, 1, 3},
{CAP_Z, UDATPG_ZONE_FIELD, DT_LONG - DT_DELTA, 4, 0},
- {0, UDATPG_FIELD_COUNT, 0, 0, 0} , // last row of dtTypes[]
+ {CAP_V, UDATPG_ZONE_FIELD, DT_SHORT - DT_DELTA, 1, 3},
+ {CAP_V, UDATPG_ZONE_FIELD, DT_LONG - DT_DELTA, 4, 0},
+ {0, UDATPG_FIELD_COUNT, 0, 0, 0} , // last row of dtTypes[]
};
static const char* const CLDR_FIELD_APPEND[] = {
static const char* const CLDR_FIELD_NAME[] = {
"era", "year", "quarter", "month", "week", "*", "weekday", "day", "*", "*", "dayperiod",
"hour", "minute", "second", "*", "zone"
-};
+};
static const char* const Resource_Fields[] = {
"day", "dayperiod", "era", "hour", "minute", "month", "second", "week",
return result;
}
-DateTimePatternGenerator::DateTimePatternGenerator(UErrorCode &status) :
+DateTimePatternGenerator::DateTimePatternGenerator(UErrorCode &status) :
skipMatcher(NULL),
fAvailableFormatKeyHash(NULL)
{
}
}
-DateTimePatternGenerator::DateTimePatternGenerator(const DateTimePatternGenerator& other) :
+DateTimePatternGenerator::DateTimePatternGenerator(const DateTimePatternGenerator& other) :
UObject(),
skipMatcher(NULL),
fAvailableFormatKeyHash(NULL)
{
fp = new FormatParser();
- dtMatcher = new DateTimeMatcher();
+ dtMatcher = new DateTimeMatcher();
distanceInfo = new DistanceInfo();
patternMap = new PatternMap();
*this=other;
if (fAvailableFormatKeyHash!=NULL) {
delete fAvailableFormatKeyHash;
}
-
- if (fp != NULL) delete fp;
+
+ if (fp != NULL) delete fp;
if (dtMatcher != NULL) delete dtMatcher;
if (distanceInfo != NULL) delete distanceInfo;
if (patternMap != NULL) delete patternMap;
void
DateTimePatternGenerator::initData(const Locale& locale, UErrorCode &status) {
//const char *baseLangName = locale.getBaseName(); // unused
-
+
skipMatcher = NULL;
fAvailableFormatKeyHash=NULL;
addCanonicalItems();
if (U_FAILURE(status)) {
return;
}
- addCLDRData(locale);
+ addCLDRData(locale, status);
setDateTimeFromCalendar(locale, status);
setDecimalSymbols(locale, status);
} // DateTimePatternGenerator::initData
for (int32_t i=DateFormat::kFull; i<=DateFormat::kShort; i++) {
DateFormat::EStyle style = (DateFormat::EStyle)i;
df = DateFormat::createDateInstance(style, locale);
- if (df != NULL && df->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
- SimpleDateFormat* sdf = (SimpleDateFormat*)df;
+ SimpleDateFormat* sdf;
+ if (df != NULL && (sdf = dynamic_cast<SimpleDateFormat*>(df)) != NULL) {
conflictingStatus = addPattern(sdf->toPattern(dfPattern), FALSE, conflictingString, status);
}
// TODO Maybe we should return an error when the date format isn't simple.
}
df = DateFormat::createTimeInstance(style, locale);
- if (df != NULL && df->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
- SimpleDateFormat* sdf = (SimpleDateFormat*)df;
+ if (df != NULL && (sdf = dynamic_cast<SimpleDateFormat*>(df)) != NULL) {
conflictingStatus = addPattern(sdf->toPattern(dfPattern), FALSE, conflictingString, status);
// HACK for hh:ss
if ( i==DateFormat::kMedium ) {
DateTimePatternGenerator::hackTimes(const UnicodeString& hackPattern, UErrorCode& status) {
UDateTimePatternConflict conflictingStatus;
UnicodeString conflictingString;
-
+
fp->set(hackPattern);
UnicodeString mmss;
UBool gotMm=FALSE;
static const UChar hourFormatChars[] = { CAP_H, LOW_H, CAP_K, LOW_K, 0 }; // HhKk, the hour format characters
void
-DateTimePatternGenerator::addCLDRData(const Locale& locale) {
- UErrorCode err = U_ZERO_ERROR;
+DateTimePatternGenerator::addCLDRData(const Locale& locale, UErrorCode& err) {
UResourceBundle *rb, *calTypeBundle, *calBundle;
UResourceBundle *patBundle, *fieldBundle, *fBundle;
UnicodeString rbPattern, value, field;
UnicodeString defaultItemFormat(TRUE, UDATPG_ItemFormat, LENGTHOF(UDATPG_ItemFormat)-1); // Read-only alias.
+ err = U_ZERO_ERROR;
+
fDefaultHourFormatChar = 0;
for (i=0; i<UDATPG_FIELD_COUNT; ++i ) {
appendItemNames[i]=CAP_F;
}
rb = ures_open(NULL, locale.getName(), &err);
- const char *curLocaleName=ures_getLocale(rb, &err);
+ if (rb == NULL || U_FAILURE(err)) {
+ return;
+ }
+ const char *curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &err);
const char * calendarTypeToUse = DT_DateTimeGregorianTag; // initial default
char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well
if ( U_SUCCESS(err) ) {
} else if (dtCount==4) { // short time format
// set fDefaultHourFormatChar to the hour format character from this pattern
int32_t tfIdx, tfLen = rbPattern.length();
+ UBool ignoreChars = FALSE;
for (tfIdx = 0; tfIdx < tfLen; tfIdx++) {
UChar tfChar = rbPattern.charAt(tfIdx);
- if ( u_strchr(hourFormatChars, tfChar) != NULL ) {
+ if ( tfChar == SINGLE_QUOTE ) {
+ ignoreChars = !ignoreChars; // toggle (handle quoted literals & '' for single quote)
+ } else if ( !ignoreChars && u_strchr(hourFormatChars, tfChar) != NULL ) {
fDefaultHourFormatChar = tfChar;
break;
}
}
}
}
- };
+ }
ures_close(patBundle);
-
+
err = U_ZERO_ERROR;
patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeAppendItemsTag, NULL, &err);
key=NULL;
}
}
ures_close(patBundle);
-
+
key=NULL;
err = U_ZERO_ERROR;
fBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeFieldsTag, NULL, &err);
patBundle = ures_getByKeyWithFallback(fBundle, Resource_Fields[i], NULL, &err);
fieldBundle = ures_getByKeyWithFallback(patBundle, "dn", NULL, &err);
rbPattern = ures_getNextUnicodeString(fieldBundle, &key, &err);
- ures_close(fieldBundle);
+ ures_close(fieldBundle);
ures_close(patBundle);
if (rbPattern.length()==0 ) {
- continue;
+ continue;
}
else {
setAppendItemName(getAppendNameNumber(Resource_Fields[i]), rbPattern);
ures_close(calTypeBundle);
ures_close(calBundle);
ures_close(rb);
-
+
err = U_ZERO_ERROR;
char parentLocale[50];
int32_t localeNameLen=0;
uprv_strcpy(parentLocale, curLocaleName);
while((localeNameLen=uloc_getParent(parentLocale, parentLocale, 50, &err))>=0 ) {
rb = ures_open(NULL, parentLocale, &err);
- curLocaleName=ures_getLocale(rb, &err);
+ curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &err);
uprv_strcpy(parentLocale, curLocaleName);
calBundle = ures_getByKey(rb, DT_DateTimeCalendarTag, NULL, &err);
calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &err);
retPattern=ures_a_getNextString(&aiter, &len, &key, &err);
#else
retPattern=ures_getNextString(patBundle, &len, &key, &err);
-#endif
+#endif
UnicodeString format=UnicodeString(retPattern);
UnicodeString retKey=UnicodeString(key, -1, US_INV);
if ( !isAvailableFormatSet(retKey) ) {
UnicodeString
DateTimePatternGenerator::getBestPattern(const UnicodeString& patternForm, UErrorCode& status) {
+ return getBestPattern(patternForm, UDATPG_MATCH_NO_OPTIONS, status);
+}
+
+UnicodeString
+DateTimePatternGenerator::getBestPattern(const UnicodeString& patternForm, UDateTimePatternMatchOptions options, UErrorCode& status) {
const UnicodeString *bestPattern=NULL;
UnicodeString dtFormat;
UnicodeString resultPattern;
int32_t dateMask=(1<<UDATPG_DAYPERIOD_FIELD) - 1;
int32_t timeMask=(1<<UDATPG_FIELD_COUNT) - 1 - dateMask;
-
+
UnicodeString patternFormCopy = UnicodeString(patternForm);
patternFormCopy.findAndReplace(UnicodeString(LOW_J), UnicodeString(fDefaultHourFormatChar));
-
+
resultPattern.remove();
dtMatcher->set(patternFormCopy, fp);
const PtnSkeleton* specifiedSkeleton=NULL;
bestPattern=getBestRaw(*dtMatcher, -1, distanceInfo, &specifiedSkeleton);
if ( distanceInfo->missingFieldMask==0 && distanceInfo->extraFieldMask==0 ) {
- resultPattern = adjustFieldTypes(*bestPattern, specifiedSkeleton, FALSE);
+ resultPattern = adjustFieldTypes(*bestPattern, specifiedSkeleton, FALSE, options);
return resultPattern;
}
int32_t neededFields = dtMatcher->getFieldMask();
- UnicodeString datePattern=getBestAppending(neededFields & dateMask);
- UnicodeString timePattern=getBestAppending(neededFields & timeMask);
+ UnicodeString datePattern=getBestAppending(neededFields & dateMask, options);
+ UnicodeString timePattern=getBestAppending(neededFields & timeMask, options);
if (datePattern.length()==0) {
if (timePattern.length()==0) {
resultPattern.remove();
}
UnicodeString
-DateTimePatternGenerator::replaceFieldTypes(const UnicodeString& pattern,
- const UnicodeString& skeleton,
+DateTimePatternGenerator::replaceFieldTypes(const UnicodeString& pattern,
+ const UnicodeString& skeleton,
+ UErrorCode& status) {
+ return replaceFieldTypes(pattern, skeleton, UDATPG_MATCH_NO_OPTIONS, status);
+}
+
+UnicodeString
+DateTimePatternGenerator::replaceFieldTypes(const UnicodeString& pattern,
+ const UnicodeString& skeleton,
+ UDateTimePatternMatchOptions options,
UErrorCode& /*status*/) {
dtMatcher->set(skeleton, fp);
- UnicodeString result = adjustFieldTypes(pattern, NULL, FALSE);
+ UnicodeString result = adjustFieldTypes(pattern, NULL, FALSE, options);
return result;
}
DateTimePatternGenerator::setDateTimeFromCalendar(const Locale& locale, UErrorCode& status) {
const UChar *resStr;
int32_t resStrLen = 0;
-
+
Calendar* fCalendar = Calendar::createInstance(locale, status);
CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
UResourceBundle *dateTimePatterns = calData.getByKey(DT_DateTimePatternsTag, status);
}
resStr = ures_getStringByIndex(dateTimePatterns, (int32_t)DateFormat::kDateTime, &resStrLen, &status);
setDateTimeFormat(UnicodeString(TRUE, resStr, resStrLen));
-
+
delete fCalendar;
}
if(U_FAILURE(status)) {
return conflictingStatus;
}
-
+
return UDATPG_NO_CONFLICT;
}
UnicodeString
DateTimePatternGenerator::adjustFieldTypes(const UnicodeString& pattern,
const PtnSkeleton* specifiedSkeleton,
- UBool fixFractionalSeconds) {
+ UBool fixFractionalSeconds,
+ UDateTimePatternMatchOptions options) {
UnicodeString newPattern;
fp->set(pattern);
for (int32_t i=0; i < fp->itemNumber; i++) {
if (fixFractionalSeconds && typeValue == UDATPG_SECOND_FIELD) {
UnicodeString newField=dtMatcher->skeleton.original[UDATPG_FRACTIONAL_SECOND_FIELD];
field = field + decimal + newField;
- }
- else {
- if (dtMatcher->skeleton.type[typeValue]!=0) {
+ } else if (dtMatcher->skeleton.type[typeValue]!=0) {
// Here:
// - "reqField" is the field from the originally requested skeleton, with length
// "reqFieldLen".
// - "field" is the field from the found pattern.
//
// The adjusted field should consist of characters from the originally requested
- // skeleton, except in the case of UDATPG_HOUR_FIELD or UDATPG_MONTH_FIELD, in
- // which case it should consist of characters from the found pattern.
+ // skeleton, except in the case of UDATPG_HOUR_FIELD or UDATPG_MONTH_FIELD or
+ // UDATPG_WEEKDAY_FIELD, in which case it should consist of characters from the
+ // found pattern.
//
// The length of the adjusted field (adjFieldLen) should match that in the originally
- // requested skeleton, except that if there is a specified skeleton for the found pattern
- // and one of the following is true, then the length of the adjusted field should match
- // that in the found pattern (i.e. the length of this pattern field should not be adjusted):
- // a) The length of the field in the skeleton (skelFieldLen) is equal to reqFieldLen.
- // b) The pattern field is numeric and the skeleton field is not, or vice versa.
+ // requested skeleton, except that in the following cases the length of the adjusted field
+ // should match that in the found pattern (i.e. the length of this pattern field should
+ // not be adjusted):
+ // 1. typeValue is UDATPG_HOUR_FIELD/MINUTE/SECOND and the corresponding bit in options is
+ // not set (ticket #7180). Note, we may want to implement a similar change for other
+ // numeric fields (MM, dd, etc.) so the default behavior is to get locale preference for
+ // field length, but options bits can be used to override this.
+ // 2. There is a specified skeleton for the found pattern and one of the following is true:
+ // a) The length of the field in the skeleton (skelFieldLen) is equal to reqFieldLen.
+ // b) The pattern field is numeric and the skeleton field is not, or vice versa.
UnicodeString reqField = dtMatcher->skeleton.original[typeValue];
int32_t reqFieldLen = reqField.length();
+ if (reqField.charAt(0) == CAP_E && reqFieldLen < 3)
+ reqFieldLen = 3; // 1-3 for E are equivalent to 3 for c,e
int32_t adjFieldLen = reqFieldLen;
- if (specifiedSkeleton) {
+ if ( (typeValue==UDATPG_HOUR_FIELD && (options & UDATPG_MATCH_HOUR_FIELD_LENGTH)==0) ||
+ (typeValue==UDATPG_MINUTE_FIELD && (options & UDATPG_MATCH_MINUTE_FIELD_LENGTH)==0) ||
+ (typeValue==UDATPG_SECOND_FIELD && (options & UDATPG_MATCH_SECOND_FIELD_LENGTH)==0) ) {
+ adjFieldLen = field.length();
+ } else if (specifiedSkeleton) {
UnicodeString skelField = specifiedSkeleton->original[typeValue];
int32_t skelFieldLen = skelField.length();
UBool patFieldIsNumeric = (row->type > 0);
adjFieldLen = field.length();
}
}
- UChar c = (typeValue!= UDATPG_HOUR_FIELD && typeValue!= UDATPG_MONTH_FIELD)? reqField.charAt(0): field.charAt(0);
+ UChar c = (typeValue!= UDATPG_HOUR_FIELD && typeValue!= UDATPG_MONTH_FIELD && typeValue!= UDATPG_WEEKDAY_FIELD)?
+ reqField.charAt(0): field.charAt(0);
field.remove();
for (int32_t i=adjFieldLen; i>0; --i) {
field+=c;
}
- }
- newPattern+=field;
}
+ newPattern+=field;
}
}
return newPattern;
}
UnicodeString
-DateTimePatternGenerator::getBestAppending(int32_t missingFields) {
- UnicodeString resultPattern, tempPattern, formattedPattern;
+DateTimePatternGenerator::getBestAppending(int32_t missingFields, UDateTimePatternMatchOptions options) {
+ UnicodeString resultPattern, tempPattern;
UErrorCode err=U_ZERO_ERROR;
int32_t lastMissingFieldMask=0;
if (missingFields!=0) {
resultPattern=UnicodeString();
const PtnSkeleton* specifiedSkeleton=NULL;
tempPattern = *getBestRaw(*dtMatcher, missingFields, distanceInfo, &specifiedSkeleton);
- resultPattern = adjustFieldTypes(tempPattern, specifiedSkeleton, FALSE);
+ resultPattern = adjustFieldTypes(tempPattern, specifiedSkeleton, FALSE, options);
if ( distanceInfo->missingFieldMask==0 ) {
return resultPattern;
}
}
if (((distanceInfo->missingFieldMask & UDATPG_SECOND_AND_FRACTIONAL_MASK)==UDATPG_FRACTIONAL_MASK) &&
((missingFields & UDATPG_SECOND_AND_FRACTIONAL_MASK) == UDATPG_SECOND_AND_FRACTIONAL_MASK)) {
- resultPattern = adjustFieldTypes(resultPattern, specifiedSkeleton, FALSE);
- //resultPattern = tempPattern;
+ resultPattern = adjustFieldTypes(resultPattern, specifiedSkeleton, TRUE, options);
distanceInfo->missingFieldMask &= ~UDATPG_FRACTIONAL_MASK;
continue;
}
int32_t startingMask = distanceInfo->missingFieldMask;
tempPattern = *getBestRaw(*dtMatcher, distanceInfo->missingFieldMask, distanceInfo, &specifiedSkeleton);
- tempPattern = adjustFieldTypes(tempPattern, specifiedSkeleton, FALSE);
+ tempPattern = adjustFieldTypes(tempPattern, specifiedSkeleton, FALSE, options);
int32_t foundMask=startingMask& ~distanceInfo->missingFieldMask;
int32_t topField=getTopBitNumber(foundMask);
UnicodeString appendName;
appendName
};
UnicodeString emptyStr;
- formattedPattern = MessageFormat::format(appendItemFormats[topField], formatPattern, 3, emptyStr, err);
+ resultPattern = MessageFormat::format(appendItemFormats[topField], formatPattern, 3, emptyStr, err);
lastMissingFieldMask = distanceInfo->missingFieldMask;
}
}
- return formattedPattern;
+ return resultPattern;
}
int32_t
if (i-1 >UDATPG_ZONE_FIELD) {
return UDATPG_ZONE_FIELD;
}
- else
+ else
return i-1;
}
const UnicodeString&
DateTimePatternGenerator::getPatternForSkeleton(const UnicodeString& skeleton) const {
PtnElem *curElem;
-
+
if (skeleton.length() ==0) {
return emptyString;
- }
+ }
curElem = patternMap->getHeader(skeleton.charAt(0));
while ( curElem != NULL ) {
if ( curElem->skeleton->getSkeleton()==skeleton ) {
*skipMatcher = current;
}
UnicodeString trial = getBestPattern(current.getPattern(), status);
- if (trial == *pattern) {
+ if (trial == *pattern) {
((DTRedundantEnumeration *)output)->add(*pattern, status);
}
if (current.equals(skipMatcher)) {
}
}
-PtnElem*
+PtnElem*
PatternMap::getHeader(UChar baseChar) {
PtnElem* curElem;
-
+
if ( (baseChar >= CAP_A) && (baseChar <= CAP_Z) ) {
curElem = boot[baseChar-CAP_A];
}
}
return curElem;
}
-
+
PatternMap::~PatternMap() {
for (int32_t i=0; i < MAX_PATTERN_ENTRIES; ++i ) {
if (boot[i]!=NULL ) {
break;
}
}
-
+
if ((curElem=getHeader(baseChar))==NULL) {
return NULL; // no match
}
}while (curElem != NULL);
return NULL;
-}
+}
UBool
PatternMap::equals(const PatternMap& other) {
UnicodeString
DateTimeMatcher::getPattern() {
UnicodeString result;
-
+
for (int32_t i=0; i<UDATPG_FIELD_COUNT; ++i ) {
if (skeleton.original[i].length()!=0) {
result += skeleton.original[i];
}
int32_t
-FormatParser::getCanonicalIndex(const UnicodeString& s) {
+FormatParser::getCanonicalIndex(const UnicodeString& s, UBool strict) {
int32_t len = s.length();
+ if (len == 0) {
+ return -1;
+ }
UChar ch = s.charAt(0);
- int32_t i=0;
- while (dtTypes[i].patternChar!='\0') {
- if ( dtTypes[i].patternChar!=ch ) {
+ // Verify that all are the same character.
+ for (int32_t l = 1; l < len; l++) {
+ if (ch != s.charAt(l)) {
+ return -1;
+ }
+ }
+ int32_t i = 0;
+ int32_t bestRow = -1;
+ while (dtTypes[i].patternChar != '\0') {
+ if ( dtTypes[i].patternChar != ch ) {
++i;
continue;
}
- if (dtTypes[i].patternChar!=dtTypes[i+1].patternChar) {
+ bestRow = i;
+ if (dtTypes[i].patternChar != dtTypes[i+1].patternChar) {
return i;
}
if (dtTypes[i+1].minLen <= len) {
}
return i;
}
- return -1;
+ return strict ? -1 : bestRow;
}
UBool
void
FormatParser::getQuoteLiteral(UnicodeString& quote, int32_t *itemIndex) {
int32_t i=*itemIndex;
-
+
quote.remove();
if (items[i].charAt(0)==SINGLE_QUOTE) {
quote += items[i];
this->patternMap=&newPatternMap;
}
-PtnSkeleton*
+PtnSkeleton*
PatternMapIterator::getSkeleton() {
if ( nodePtr == NULL ) {
return NULL;
PtnSkeleton::~PtnSkeleton() {
}
-PtnElem::PtnElem(const UnicodeString &basePat, const UnicodeString &pat) :
+PtnElem::PtnElem(const UnicodeString &basePat, const UnicodeString &pat) :
basePattern(basePat),
skeleton(NULL),
pattern(pat),