ICU-4084 Improve DateFormat construction performance.
X-SVN-Rev: 16223
This commit is contained in:
parent
b637e0ffb0
commit
db7d00f2cb
@ -23,7 +23,6 @@
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/dtfmtsym.h"
|
||||
#include "unicode/resbund.h"
|
||||
#include "unicode/smpdtfmt.h"
|
||||
#include "ucln_in.h"
|
||||
#include "mutex.h"
|
||||
@ -40,7 +39,7 @@
|
||||
* resource data.
|
||||
*/
|
||||
|
||||
#define PATTERN_CHARS_LEN 20
|
||||
#define PATTERN_CHARS_LEN 24
|
||||
|
||||
/**
|
||||
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All
|
||||
@ -48,9 +47,9 @@
|
||||
*/
|
||||
static const UChar gPatternChars[] = {
|
||||
// GyMdkHmsSEDFwWahKzYeugAZ
|
||||
0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45, 0x44,
|
||||
0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65, 0x75, 0x67,
|
||||
0x41, 0x5A, 0
|
||||
0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,
|
||||
0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,
|
||||
0x75, 0x67, 0x41, 0x5A, 0
|
||||
};
|
||||
|
||||
//------------------------------------------------------
|
||||
@ -511,14 +510,16 @@ DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChar
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
DateFormatSymbols::initField(UnicodeString **field, int32_t& length, const ResourceBundle &data, UErrorCode &status) {
|
||||
DateFormatSymbols::initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) {
|
||||
if (U_SUCCESS(status)) {
|
||||
length = data.getSize();
|
||||
int32_t strLen = 0;
|
||||
length = ures_getSize(data);
|
||||
*field = newUnicodeStringArray(length);
|
||||
if (*field) {
|
||||
for(int32_t i = 0; i<length; i++) {
|
||||
// fastCopyFrom() - see assignArray comments
|
||||
(*(field)+i)->fastCopyFrom(data.getStringEx(i, status));
|
||||
const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status);
|
||||
// setTo() - see assignArray comments
|
||||
(*(field)+i)->setTo(TRUE, resStr, strLen);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -583,9 +584,10 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
||||
UResourceBundle *nonCalendarData = ures_open((char*)0, locale.getName(), &status);
|
||||
|
||||
// load the first data item
|
||||
ResourceBundle eras(calData.getBundleByKey(gErasTag, status).getWithFallback(gAbbreviatedTag, status));
|
||||
ResourceBundle lsweekdaysData(calData.getBundleByKey2(gDayNamesTag, gNamesAbbrTag, status));
|
||||
ResourceBundle weekdaysData(calData.getBundleByKey2(gDayNamesTag, gNamesWideTag, status));
|
||||
UResourceBundle *erasMain = calData.getByKey(gErasTag, status);
|
||||
UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gAbbreviatedTag, NULL, &status);
|
||||
UResourceBundle *lsweekdaysData = NULL; // Data closed by calData
|
||||
UResourceBundle *weekdaysData = NULL; // Data closed by calData
|
||||
UResourceBundle *zoneArray = ures_getByKey(nonCalendarData, gZoneStringsTag, NULL, &status);
|
||||
UResourceBundle *zoneRow = ures_getByIndex(zoneArray, (int32_t)0, NULL, &status);
|
||||
U_LOCALE_BASED(locBased, *this);
|
||||
@ -622,16 +624,21 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
||||
// if we make it to here, the resource data is cool, and we can get everything out
|
||||
// of it that we need except for the time-zone and localized-pattern data, which
|
||||
// are stored in a separate file
|
||||
locBased.setLocaleIDs(eras.getLocale(ULOC_VALID_LOCALE, status).getName(),
|
||||
eras.getLocale(ULOC_ACTUAL_LOCALE, status).getName());
|
||||
locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status),
|
||||
ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status));
|
||||
initField(&fEras, fErasCount, eras, status);
|
||||
initField(&fMonths, fMonthsCount, calData.getBundleByKey2(gMonthNamesTag, gNamesWideTag, status), status);
|
||||
initField(&fShortMonths, fShortMonthsCount, calData.getBundleByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
|
||||
initField(&fAmPms, fAmPmsCount, calData.getBundleByKey(gAmPmMarkersTag, status), status);
|
||||
initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
|
||||
initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
|
||||
initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status);
|
||||
|
||||
// fastCopyFrom()/setTo() - see assignArray comments
|
||||
resStr = ures_getStringByKey(nonCalendarData, gLocalPatternCharsTag, &len, &status);
|
||||
fLocalPatternChars.setTo(TRUE, resStr, len);
|
||||
// If the locale data does not include new pattern chars, use the defaults
|
||||
// TODO: Consider making this an error, since this may add conflicting characters.
|
||||
if (len < PATTERN_CHARS_LEN) {
|
||||
fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
|
||||
}
|
||||
|
||||
/* TODO: Fix the case where the zoneStrings is not a perfect square array of information. */
|
||||
fZoneStringsRowCount = ures_getSize(zoneArray);
|
||||
@ -658,7 +665,8 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
||||
}
|
||||
|
||||
// {sfb} fixed to handle 1-based weekdays
|
||||
fWeekdaysCount = weekdaysData.getSize();
|
||||
weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
|
||||
fWeekdaysCount = ures_getSize(weekdaysData);
|
||||
fWeekdays = new UnicodeString[fWeekdaysCount+1];
|
||||
/* test for NULL */
|
||||
if (fWeekdays == 0) {
|
||||
@ -667,12 +675,14 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
||||
}
|
||||
// leave fWeekdays[0] empty
|
||||
for(i = 0; i<fWeekdaysCount; i++) {
|
||||
// fastCopyFrom() - see assignArray comments
|
||||
fWeekdays[i+1].fastCopyFrom(weekdaysData.getStringEx(i, status));
|
||||
resStr = ures_getStringByIndex(weekdaysData, i, &len, &status);
|
||||
// setTo() - see assignArray comments
|
||||
fWeekdays[i+1].setTo(TRUE, resStr, len);
|
||||
}
|
||||
fWeekdaysCount++;
|
||||
|
||||
fShortWeekdaysCount = lsweekdaysData.getSize();
|
||||
lsweekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
|
||||
fShortWeekdaysCount = ures_getSize(lsweekdaysData);
|
||||
fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1];
|
||||
/* test for NULL */
|
||||
if (fShortWeekdays == 0) {
|
||||
@ -681,16 +691,11 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
||||
}
|
||||
// leave fShortWeekdays[0] empty
|
||||
for(i = 0; i<fShortWeekdaysCount; i++) {
|
||||
// fastCopyFrom() - see assignArray comments
|
||||
fShortWeekdays[i+1].fastCopyFrom(lsweekdaysData.getStringEx(i, status));
|
||||
resStr = ures_getStringByIndex(lsweekdaysData, i, &len, &status);
|
||||
// setTo() - see assignArray comments
|
||||
fShortWeekdays[i+1].setTo(TRUE, resStr, len);
|
||||
}
|
||||
fShortWeekdaysCount++;
|
||||
|
||||
// If the locale data does not include new pattern chars, use the defaults
|
||||
len = fLocalPatternChars.length();
|
||||
if (len < PATTERN_CHARS_LEN) {
|
||||
fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
|
||||
}
|
||||
cleanup:
|
||||
ures_close(zoneRow);
|
||||
ures_close(zoneArray);
|
||||
|
@ -174,63 +174,59 @@ void CalendarData::initData(const char *locale, const char *type, UErrorCode& st
|
||||
}
|
||||
|
||||
CalendarData::~CalendarData() {
|
||||
ures_close(fFillin);
|
||||
ures_close(fBundle);
|
||||
ures_close(fFallback);
|
||||
ures_close(fOtherFillin);
|
||||
ures_close(fFillin);
|
||||
ures_close(fBundle);
|
||||
ures_close(fFallback);
|
||||
ures_close(fOtherFillin);
|
||||
}
|
||||
|
||||
UResourceBundle*
|
||||
CalendarData::getByKey(const char *key, UErrorCode& status) {
|
||||
if(U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if(U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(fBundle) {
|
||||
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
|
||||
if(fBundle) {
|
||||
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
|
||||
#if defined (U_DEBUG_CALDATA)
|
||||
fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
|
||||
fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
|
||||
#endif
|
||||
}
|
||||
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
|
||||
status = U_ZERO_ERROR; // retry with fallback (gregorian)
|
||||
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
|
||||
}
|
||||
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
|
||||
status = U_ZERO_ERROR; // retry with fallback (gregorian)
|
||||
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
|
||||
#if defined (U_DEBUG_CALDATA)
|
||||
fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
|
||||
fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status));
|
||||
#endif
|
||||
}
|
||||
return fFillin;
|
||||
}
|
||||
|
||||
ResourceBundle CalendarData::getBundleByKey(const char *key, UErrorCode &status) {
|
||||
return ResourceBundle(getByKey(key,status), status);
|
||||
}
|
||||
return fFillin;
|
||||
}
|
||||
|
||||
UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UErrorCode& status) {
|
||||
if(U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if(U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(fBundle) {
|
||||
if(fBundle) {
|
||||
#if defined (U_DEBUG_CALDATA)
|
||||
fprintf(stderr, "%p: //\n");
|
||||
fprintf(stderr, "%p: //\n");
|
||||
#endif
|
||||
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
|
||||
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
|
||||
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
|
||||
fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status);
|
||||
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
|
||||
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
|
||||
#if defined (U_DEBUG_CALDATA)
|
||||
fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status));
|
||||
fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status));
|
||||
#endif
|
||||
}
|
||||
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
|
||||
status = U_ZERO_ERROR; // retry with fallback (gregorian)
|
||||
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
|
||||
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
|
||||
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
|
||||
}
|
||||
if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) {
|
||||
status = U_ZERO_ERROR; // retry with fallback (gregorian)
|
||||
fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status);
|
||||
fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status);
|
||||
fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status);
|
||||
#if defined (U_DEBUG_CALDATA)
|
||||
fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status));
|
||||
fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//// handling of 'default' keyword on failure: Commented out for 3.0.
|
||||
// if((status == U_MISSING_RESOURCE_ERROR) &&
|
||||
@ -265,11 +261,7 @@ UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UE
|
||||
// }
|
||||
// }
|
||||
|
||||
return fFillin;
|
||||
}
|
||||
|
||||
ResourceBundle CalendarData::getBundleByKey2(const char *key, const char *subKey, UErrorCode& status) {
|
||||
return ResourceBundle(getByKey2(key, subKey, status), status);
|
||||
return fFillin;
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CalendarData);
|
||||
|
@ -262,66 +262,41 @@ inline int32_t Grego::gregorianShift(int32_t eyear) {
|
||||
* @internal ICU 3.0
|
||||
*/
|
||||
class U_I18N_API CalendarData : public UObject {
|
||||
public:
|
||||
/**
|
||||
* Construct a CalendarData from the given locale.
|
||||
* @param loc locale to use - the 'calendar' keyword will be used, respecting the
|
||||
* 'default' value in the resource bundle.
|
||||
* @param status error code
|
||||
*/
|
||||
//CalendarData(const Locale& loc, UErrorCode& status);
|
||||
public:
|
||||
/**
|
||||
* Construct a CalendarData from the given locale.
|
||||
* @param loc locale to use. The 'calendar' keyword will be ignored.
|
||||
* @param type calendar type. NULL indicates the gregorian calendar.
|
||||
* No default lookup is done.
|
||||
* @param status error code
|
||||
*/
|
||||
CalendarData(const Locale& loc, const char *type, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Construct a CalendarData from the given locale.
|
||||
* @param loc locale to use. The 'calendar' keyword will be ignored.
|
||||
* @param type calendar type. NULL indicates the gregorian calendar.
|
||||
* No default lookup is done.
|
||||
* @param status error code
|
||||
*/
|
||||
CalendarData(const Locale& loc, const char *type, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
|
||||
*
|
||||
* @param key Resource key to data
|
||||
* @param status Error Status
|
||||
* @internal
|
||||
*/
|
||||
UResourceBundle* getByKey(const char *key, UErrorCode& status);
|
||||
/**
|
||||
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
|
||||
* The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
|
||||
*
|
||||
* @param key Resource key to data
|
||||
* @param status Error Status
|
||||
* @internal
|
||||
*/
|
||||
UResourceBundle* getByKey(const char *key, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Load data for calendar. returns a ResourceBundle object
|
||||
*
|
||||
* @param key Resource key to data
|
||||
* @param status Error Status
|
||||
* @internal
|
||||
*/
|
||||
ResourceBundle getBundleByKey(const char *key, UErrorCode& status);
|
||||
/**
|
||||
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
|
||||
* There is an implicit key of 'format'
|
||||
* data is located in: "calendar/key/format/subKey"
|
||||
* for example, calendar/dayNames/format/abbreviated
|
||||
* The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
|
||||
*
|
||||
* @param key Resource key to data
|
||||
* @param subKey Resource key to data
|
||||
* @param status Error Status
|
||||
* @internal
|
||||
*/
|
||||
UResourceBundle* getByKey2(const char *key, const char *subKey, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
|
||||
* There is an implicit key of 'format'
|
||||
* data is located in: "calendar/key/format/subKey"
|
||||
* for example, calendar/dayNames/format/abbreviated
|
||||
*
|
||||
* @param key Resource key to data
|
||||
* @param subKey Resource key to data
|
||||
* @param status Error Status
|
||||
* @internal
|
||||
*/
|
||||
UResourceBundle* getByKey2(const char *key, const char *subKey, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Load data for calendar. Returns a ResourceBundle object
|
||||
*
|
||||
* @param key Resource key to data
|
||||
* @param subKey Resource key to data
|
||||
* @param status Error Status
|
||||
* @internal
|
||||
*/
|
||||
ResourceBundle getBundleByKey2(const char *key, const char *subKey, UErrorCode& status);
|
||||
|
||||
~CalendarData();
|
||||
~CalendarData();
|
||||
|
||||
/**
|
||||
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
|
||||
@ -348,14 +323,14 @@ class U_I18N_API CalendarData : public UObject {
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
private:
|
||||
void initData(const char *locale, const char *type, UErrorCode& status);
|
||||
|
||||
UResourceBundle *fFillin;
|
||||
UResourceBundle *fOtherFillin;
|
||||
UResourceBundle *fBundle;
|
||||
UResourceBundle *fFallback;
|
||||
CalendarData(); // Not implemented.
|
||||
private:
|
||||
void initData(const char *locale, const char *type, UErrorCode& status);
|
||||
|
||||
UResourceBundle *fFillin;
|
||||
UResourceBundle *fOtherFillin;
|
||||
UResourceBundle *fBundle;
|
||||
UResourceBundle *fFallback;
|
||||
CalendarData(); // Not implemented.
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -278,7 +278,8 @@ void SimpleDateFormat::construct(EStyle timeStyle,
|
||||
initializeCalendar(NULL, locale, status);
|
||||
|
||||
CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
|
||||
ResourceBundle dateTimePatterns = calData.getBundleByKey(gDateTimePatternsTag, status);
|
||||
UResourceBundle *dtp = calData.getByKey(gDateTimePatternsTag, status);
|
||||
ResourceBundle dateTimePatterns(dtp, status);
|
||||
if (U_FAILURE(status)) return;
|
||||
|
||||
if (dateTimePatterns.getSize() <= kDateTime)
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "unicode/uobject.h"
|
||||
#include "unicode/locid.h"
|
||||
#include "unicode/resbund.h"
|
||||
#include "unicode/ures.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
@ -412,7 +412,7 @@ private:
|
||||
|
||||
DateFormatSymbols(); // default constructor not implemented
|
||||
|
||||
void initField(UnicodeString **field, int32_t& length, const ResourceBundle &data, UErrorCode &status);
|
||||
void initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status);
|
||||
void initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user