ICU-11401 Reduce cache keyspace by caching only the components of DateFormat by locale rather than actual DateFormat objects.
X-SVN-Rev: 36811
This commit is contained in:
parent
9d54e5711e
commit
a6bc072149
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -77,7 +77,8 @@ icu4c/source/extra/uconv/uconv.vcxproj.filters -text
|
||||
icu4c/source/i18n/i18n.vcxproj -text
|
||||
icu4c/source/i18n/i18n.vcxproj.filters -text
|
||||
icu4c/source/i18n/scientificnumberformatter.cpp -text
|
||||
icu4c/source/i18n/shareddatefmt.h -text
|
||||
icu4c/source/i18n/sharedcalendar.h -text
|
||||
icu4c/source/i18n/shareddateformatsymbols.h -text
|
||||
icu4c/source/i18n/shareddatetimepatterngenerator.h -text
|
||||
icu4c/source/i18n/unicode/scientificnumberformatter.h -text
|
||||
icu4c/source/io/io.vcxproj -text
|
||||
|
@ -57,6 +57,8 @@
|
||||
#include "ustrenum.h"
|
||||
#include "uassert.h"
|
||||
#include "olsontz.h"
|
||||
#include "sharedcalendar.h"
|
||||
#include "unifiedcache.h"
|
||||
|
||||
#if !UCONFIG_NO_SERVICE
|
||||
static icu::ICULocaleService* gService = NULL;
|
||||
@ -199,6 +201,27 @@ typedef enum ECalType {
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
SharedCalendar::~SharedCalendar() {
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template<> U_I18N_API
|
||||
const SharedCalendar *LocaleCacheKey<SharedCalendar>::createObject(
|
||||
const void * /*unusedCreationContext*/, UErrorCode &status) const {
|
||||
Calendar *calendar = Calendar::makeInstance(fLoc, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
SharedCalendar *shared = new SharedCalendar(calendar);
|
||||
if (shared == NULL) {
|
||||
delete calendar;
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
shared->addRef();
|
||||
return shared;
|
||||
}
|
||||
|
||||
static ECalType getCalendarType(const char *s) {
|
||||
for (int i = 0; gCalTypes[i] != NULL; i++) {
|
||||
if (uprv_stricmp(s, gCalTypes[i]) == 0) {
|
||||
@ -833,9 +856,8 @@ Calendar::createInstance(const Locale& aLocale, UErrorCode& success)
|
||||
|
||||
// Note: this is the bottleneck that actually calls the service routines.
|
||||
|
||||
Calendar* U_EXPORT2
|
||||
Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
|
||||
{
|
||||
Calendar * U_EXPORT2
|
||||
Calendar::makeInstance(const Locale& aLocale, UErrorCode& success) {
|
||||
if (U_FAILURE(success)) {
|
||||
return NULL;
|
||||
}
|
||||
@ -855,7 +877,6 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
|
||||
Calendar* c = NULL;
|
||||
|
||||
if(U_FAILURE(success) || !u) {
|
||||
delete zone;
|
||||
if(U_SUCCESS(success)) { // Propagate some kind of err
|
||||
success = U_INTERNAL_PROGRAM_ERROR;
|
||||
}
|
||||
@ -884,7 +905,6 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
|
||||
c = (Calendar*)getCalendarService(success)->get(l, LocaleKey::KIND_ANY, &actualLoc2, success);
|
||||
|
||||
if(U_FAILURE(success) || !c) {
|
||||
delete zone;
|
||||
if(U_SUCCESS(success)) {
|
||||
success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err
|
||||
}
|
||||
@ -910,7 +930,6 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
|
||||
#endif
|
||||
success = U_MISSING_RESOURCE_ERROR; // requested a calendar type which could NOT be found.
|
||||
delete c;
|
||||
delete zone;
|
||||
return NULL;
|
||||
}
|
||||
#ifdef U_DEBUG_CALSVC
|
||||
@ -933,8 +952,27 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
|
||||
c = (Calendar*)u;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
Calendar* U_EXPORT2
|
||||
Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
|
||||
{
|
||||
LocalPointer<TimeZone> zonePtr(zone);
|
||||
const SharedCalendar *shared = NULL;
|
||||
UnifiedCache::getByLocale(aLocale, shared, success);
|
||||
if (U_FAILURE(success)) {
|
||||
return NULL;
|
||||
}
|
||||
Calendar *c = (*shared)->clone();
|
||||
shared->removeRef();
|
||||
if (c == NULL) {
|
||||
success = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Now, reset calendar to default state:
|
||||
c->adoptTimeZone(zone); // Set the correct time zone
|
||||
c->adoptTimeZone(zonePtr.orphan()); // Set the correct time zone
|
||||
c->setTimeInMillis(getNow(), success); // let the new calendar have the current time.
|
||||
|
||||
return c;
|
||||
@ -954,6 +992,24 @@ Calendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
void U_EXPORT2
|
||||
Calendar::getCalendarTypeFromLocale(
|
||||
const Locale &aLocale,
|
||||
char *typeBuffer,
|
||||
int32_t typeBufferSize,
|
||||
UErrorCode &success) {
|
||||
const SharedCalendar *shared = NULL;
|
||||
UnifiedCache::getByLocale(aLocale, shared, success);
|
||||
if (U_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
uprv_strncpy(typeBuffer, (*shared)->getType(), typeBufferSize);
|
||||
shared->removeRef();
|
||||
if (typeBuffer[typeBufferSize - 1]) {
|
||||
success = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
UBool
|
||||
Calendar::operator==(const Calendar& that) const
|
||||
{
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "unicode/dtptngen.h"
|
||||
#include "unicode/udisplaycontext.h"
|
||||
#include "reldtfmt.h"
|
||||
#include "shareddatefmt.h"
|
||||
#include "shareddatetimepatterngenerator.h"
|
||||
#include "unifiedcache.h"
|
||||
|
||||
#include "cstring.h"
|
||||
#include "windtfmt.h"
|
||||
@ -44,181 +41,6 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
SharedDateFormat::~SharedDateFormat() {
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
// We must fully define LocaleCacheKey<SharedDateFormat>
|
||||
template<> U_I18N_API
|
||||
const SharedDateFormat *LocaleCacheKey<SharedDateFormat>::createObject(
|
||||
const void * /*creationContext*/, UErrorCode &status) const {
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class U_I18N_API DateFmtKeyByStyle : public LocaleCacheKey<SharedDateFormat> {
|
||||
private:
|
||||
DateFormat::EStyle fDateStyle;
|
||||
DateFormat::EStyle fTimeStyle;
|
||||
public:
|
||||
DateFmtKeyByStyle(
|
||||
const Locale &loc,
|
||||
DateFormat::EStyle dateStyle,
|
||||
DateFormat::EStyle timeStyle)
|
||||
: LocaleCacheKey<SharedDateFormat>(loc),
|
||||
fDateStyle(dateStyle),
|
||||
fTimeStyle(timeStyle) { }
|
||||
DateFmtKeyByStyle(const DateFmtKeyByStyle &other) :
|
||||
LocaleCacheKey<SharedDateFormat>(other),
|
||||
fDateStyle(other.fDateStyle),
|
||||
fTimeStyle(other.fTimeStyle) { }
|
||||
virtual ~DateFmtKeyByStyle();
|
||||
virtual int32_t hashCode() const {
|
||||
int32_t hash = 37 * LocaleCacheKey<SharedDateFormat>::hashCode() + fDateStyle;
|
||||
hash = 37 * hash + fTimeStyle;
|
||||
return hash;
|
||||
}
|
||||
virtual UBool operator==(const CacheKeyBase &other) const {
|
||||
// reflexive
|
||||
if (this == &other) {
|
||||
return TRUE;
|
||||
}
|
||||
if (!LocaleCacheKey<SharedDateFormat>::operator==(other)) {
|
||||
return FALSE;
|
||||
}
|
||||
// We know that this an other are of same class if we get this far.
|
||||
const DateFmtKeyByStyle *realOther =
|
||||
static_cast<const DateFmtKeyByStyle *>(&other);
|
||||
return (realOther->fDateStyle == fDateStyle &&
|
||||
realOther->fTimeStyle == fTimeStyle);
|
||||
}
|
||||
virtual CacheKeyBase *clone() const {
|
||||
return new DateFmtKeyByStyle(*this);
|
||||
}
|
||||
virtual const SharedDateFormat *createObject(
|
||||
const void * /*creationContext*/, UErrorCode &status) const {
|
||||
DateFormat::EStyle dateStyle = fDateStyle;
|
||||
if(dateStyle != DateFormat::kNone)
|
||||
{
|
||||
dateStyle = (DateFormat::EStyle) (dateStyle + DateFormat::kDateOffset);
|
||||
}
|
||||
DateFormat *fmt = DateFormat::create(fTimeStyle, dateStyle, fLoc);
|
||||
if (fmt == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
SharedDateFormat *result = new SharedDateFormat(fmt);
|
||||
if (result == NULL) {
|
||||
delete fmt;
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
result->addRef();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
DateFmtKeyByStyle::~DateFmtKeyByStyle() {
|
||||
}
|
||||
|
||||
class U_I18N_API DateFmtKeyBySkeleton : public LocaleCacheKey<SharedDateFormat> {
|
||||
private:
|
||||
UnicodeString fSkeleton;
|
||||
public:
|
||||
DateFmtKeyBySkeleton(const Locale &loc, const UnicodeString &skeleton) :
|
||||
LocaleCacheKey<SharedDateFormat>(loc),
|
||||
fSkeleton(skeleton) { }
|
||||
DateFmtKeyBySkeleton(const DateFmtKeyBySkeleton &other) :
|
||||
LocaleCacheKey<SharedDateFormat>(other),
|
||||
fSkeleton(other.fSkeleton) { }
|
||||
virtual ~DateFmtKeyBySkeleton();
|
||||
virtual int32_t hashCode() const {
|
||||
return 37 * LocaleCacheKey<SharedDateFormat>::hashCode() + fSkeleton.hashCode();
|
||||
}
|
||||
virtual UBool operator==(const CacheKeyBase &other) const {
|
||||
// reflexive
|
||||
if (this == &other) {
|
||||
return TRUE;
|
||||
}
|
||||
if (!LocaleCacheKey<SharedDateFormat>::operator==(other)) {
|
||||
return FALSE;
|
||||
}
|
||||
// We know that this an other are of same class if we get this far.
|
||||
const DateFmtKeyBySkeleton *realOther =
|
||||
static_cast<const DateFmtKeyBySkeleton *>(&other);
|
||||
return (realOther->fSkeleton == fSkeleton);
|
||||
}
|
||||
virtual CacheKeyBase *clone() const {
|
||||
return new DateFmtKeyBySkeleton(*this);
|
||||
}
|
||||
virtual const SharedDateFormat *createObject(
|
||||
const void *creationContext, UErrorCode &status) const {
|
||||
void *mutableCreationContext = const_cast<void *>(creationContext);
|
||||
DateTimePatternGenerator *ownedDtpg = NULL;
|
||||
DateTimePatternGenerator *dtpg =
|
||||
static_cast<DateTimePatternGenerator *>(mutableCreationContext);
|
||||
if (dtpg == NULL) {
|
||||
ownedDtpg = DateTimePatternGenerator::createInstance(fLoc, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
dtpg = ownedDtpg;
|
||||
}
|
||||
DateFormat *fmt = new SimpleDateFormat(
|
||||
dtpg->getBestPattern(fSkeleton, status),
|
||||
fLoc,
|
||||
status);
|
||||
delete ownedDtpg;
|
||||
if (fmt == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
delete fmt;
|
||||
return NULL;
|
||||
}
|
||||
SharedDateFormat *result = new SharedDateFormat(fmt);
|
||||
if (result == NULL) {
|
||||
delete fmt;
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
result->addRef();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
DateFmtKeyBySkeleton::~DateFmtKeyBySkeleton() {
|
||||
}
|
||||
|
||||
static DateFormat *createFromCache(
|
||||
const CacheKey<SharedDateFormat> &key,
|
||||
const void *context,
|
||||
UErrorCode &status) {
|
||||
const UnifiedCache *cache = UnifiedCache::getInstance(status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
const SharedDateFormat *ptr = NULL;
|
||||
cache->get(key, context, ptr, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
DateFormat *result = static_cast<DateFormat *>((*ptr)->clone());
|
||||
ptr->removeRef();
|
||||
if (result == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
} else {
|
||||
// Set the currently active default TimeZone,
|
||||
// because the cached instance might be created
|
||||
// with another TimeZone.
|
||||
// Note: We could do some optimization in SharedDateFormat
|
||||
// to pick up the current default without cloning old default.
|
||||
result->adoptTimeZone(TimeZone::createDefault());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DateFormat::DateFormat()
|
||||
: fCalendar(0),
|
||||
fNumberFormat(0),
|
||||
@ -487,9 +309,7 @@ DateFormat* U_EXPORT2
|
||||
DateFormat::createTimeInstance(DateFormat::EStyle style,
|
||||
const Locale& aLocale)
|
||||
{
|
||||
DateFmtKeyByStyle key(aLocale, kNone, style);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
return createFromCache(key, NULL, status);
|
||||
return createDateTimeInstance(kNone, style, aLocale);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -498,9 +318,7 @@ DateFormat* U_EXPORT2
|
||||
DateFormat::createDateInstance(DateFormat::EStyle style,
|
||||
const Locale& aLocale)
|
||||
{
|
||||
DateFmtKeyByStyle key(aLocale, style, kNone);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
return createFromCache(key, NULL, status);
|
||||
return createDateTimeInstance(style, kNone, aLocale);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -510,9 +328,11 @@ DateFormat::createDateTimeInstance(EStyle dateStyle,
|
||||
EStyle timeStyle,
|
||||
const Locale& aLocale)
|
||||
{
|
||||
DateFmtKeyByStyle key(aLocale, dateStyle, timeStyle);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
return createFromCache(key, NULL, status);
|
||||
if(dateStyle != kNone)
|
||||
{
|
||||
dateStyle = (EStyle) (dateStyle + kDateOffset);
|
||||
}
|
||||
return create(timeStyle, dateStyle, aLocale);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -520,9 +340,7 @@ DateFormat::createDateTimeInstance(EStyle dateStyle,
|
||||
DateFormat* U_EXPORT2
|
||||
DateFormat::createInstance()
|
||||
{
|
||||
DateFmtKeyByStyle key(Locale::getDefault(), kShort, kShort);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
return createFromCache(key, NULL, status);
|
||||
return createDateTimeInstance(kShort, kShort, Locale::getDefault());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -541,8 +359,7 @@ DateFormat::createInstanceForSkeleton(
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
DateFmtKeyBySkeleton key(locale, skeleton);
|
||||
DateFormat *result = createFromCache(key, NULL, status);
|
||||
DateFormat *result = createInstanceForSkeleton(skeleton, locale, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
@ -555,22 +372,21 @@ DateFormat::createInstanceForSkeleton(
|
||||
const UnicodeString& skeleton,
|
||||
const Locale &locale,
|
||||
UErrorCode &status) {
|
||||
LocalPointer<DateTimePatternGenerator> gen(
|
||||
DateTimePatternGenerator::createInstance(locale, status));
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
DateFmtKeyBySkeleton key(locale, skeleton);
|
||||
return createFromCache(key, NULL, status);
|
||||
return internalCreateInstanceForSkeleton(
|
||||
skeleton, locale, *gen, status);
|
||||
}
|
||||
|
||||
DateFormat* U_EXPORT2
|
||||
DateFormat::createInstanceForSkeleton(
|
||||
const UnicodeString& skeleton,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
DateFmtKeyBySkeleton key(Locale::getDefault(), skeleton);
|
||||
return createFromCache(key, NULL, status);
|
||||
return createInstanceForSkeleton(
|
||||
skeleton, Locale::getDefault(), status);
|
||||
}
|
||||
|
||||
DateFormat* U_EXPORT2
|
||||
@ -582,8 +398,19 @@ DateFormat::internalCreateInstanceForSkeleton(
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
DateFmtKeyBySkeleton key(locale, skeleton);
|
||||
return createFromCache(key, &gen, status);
|
||||
DateFormat *fmt = new SimpleDateFormat(
|
||||
gen.getBestPattern(skeleton, status),
|
||||
locale,
|
||||
status);
|
||||
if (fmt == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
delete fmt;
|
||||
return NULL;
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include "hash.h"
|
||||
#include "uresimp.h"
|
||||
#include "ureslocs.h"
|
||||
#include "shareddateformatsymbols.h"
|
||||
#include "unicode/calendar.h"
|
||||
#include "unifiedcache.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// class DateFormatSymbols
|
||||
@ -146,6 +149,32 @@ typedef enum LastResortSize {
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
SharedDateFormatSymbols::~SharedDateFormatSymbols() {
|
||||
}
|
||||
|
||||
template<> U_I18N_API
|
||||
const SharedDateFormatSymbols *
|
||||
LocaleCacheKey<SharedDateFormatSymbols>::createObject(
|
||||
const void */*unusedContext*/, UErrorCode &status) const {
|
||||
char type[256];
|
||||
Calendar::getCalendarTypeFromLocale(fLoc, type, UPRV_LENGTHOF(type), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
SharedDateFormatSymbols *shared
|
||||
= new SharedDateFormatSymbols(fLoc, type, status);
|
||||
if (shared == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
delete shared;
|
||||
return NULL;
|
||||
}
|
||||
shared->addRef();
|
||||
return shared;
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)
|
||||
|
||||
#define kSUPPLEMENTAL "supplementalData"
|
||||
@ -191,6 +220,23 @@ static inline UnicodeString* newUnicodeStringArray(size_t count) {
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
DateFormatSymbols * U_EXPORT2
|
||||
DateFormatSymbols::createForLocale(
|
||||
const Locale& locale, UErrorCode &status) {
|
||||
const SharedDateFormatSymbols *shared = NULL;
|
||||
UnifiedCache::getByLocale(locale, shared, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
DateFormatSymbols *result = new DateFormatSymbols(shared->get());
|
||||
shared->removeRef();
|
||||
if (result == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DateFormatSymbols::DateFormatSymbols(const Locale& locale,
|
||||
UErrorCode& status)
|
||||
: UObject()
|
||||
|
@ -1152,7 +1152,8 @@
|
||||
<ClInclude Include="plurrule_impl.h" />
|
||||
<ClInclude Include="quantityformatter.h" />
|
||||
<ClInclude Include="sharedbreakiterator.h" />
|
||||
<ClInclude Include="shareddatefmt.h" />
|
||||
<ClInclude Include="sharedcalendar.h" />
|
||||
<ClInclude Include="shareddateformatsymbols.h" />
|
||||
<ClInclude Include="shareddatetimepatterngenerator.h" />
|
||||
<ClInclude Include="sharednumberformat.h" />
|
||||
<ClInclude Include="sharedpluralrules.h" />
|
||||
|
@ -698,7 +698,10 @@
|
||||
<ClInclude Include="sharedbreakiterator.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shareddatefmt.h">
|
||||
<ClInclude Include="sharedcalendar.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shareddateformatsymbols.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shareddatetimepatterngenerator.h">
|
||||
|
34
icu4c/source/i18n/sharedcalendar.h
Normal file
34
icu4c/source/i18n/sharedcalendar.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* sharedcalendar.h
|
||||
*/
|
||||
|
||||
#ifndef __SHARED_CALENDAR_H__
|
||||
#define __SHARED_CALENDAR_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "sharedobject.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class Calendar;
|
||||
|
||||
class U_I18N_API SharedCalendar : public SharedObject {
|
||||
public:
|
||||
SharedCalendar(Calendar *calToAdopt) : ptr(calToAdopt) { }
|
||||
virtual ~SharedCalendar();
|
||||
const Calendar *get() const { return ptr; }
|
||||
const Calendar *operator->() const { return ptr; }
|
||||
const Calendar &operator*() const { return *ptr; }
|
||||
private:
|
||||
Calendar *ptr;
|
||||
SharedCalendar(const SharedCalendar &);
|
||||
SharedCalendar &operator=(const SharedCalendar &);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* shareddateformat.h
|
||||
*/
|
||||
|
||||
#ifndef __SHARED_DATEFORMAT_H__
|
||||
#define __SHARED_DATEFORMAT_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "sharedobject.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class DateFormat;
|
||||
|
||||
class U_I18N_API SharedDateFormat : public SharedObject {
|
||||
public:
|
||||
SharedDateFormat(DateFormat *dfToAdopt) : ptr(dfToAdopt) { }
|
||||
virtual ~SharedDateFormat();
|
||||
const DateFormat *get() const { return ptr; }
|
||||
const DateFormat *operator->() const { return ptr; }
|
||||
const DateFormat &operator*() const { return *ptr; }
|
||||
private:
|
||||
DateFormat *ptr;
|
||||
SharedDateFormat(const SharedDateFormat &);
|
||||
SharedDateFormat &operator=(const SharedDateFormat &);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
34
icu4c/source/i18n/shareddateformatsymbols.h
Normal file
34
icu4c/source/i18n/shareddateformatsymbols.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* shareddateformatsymbols.h
|
||||
*/
|
||||
|
||||
#ifndef __SHARED_DATEFORMATSYMBOLS_H__
|
||||
#define __SHARED_DATEFORMATSYMBOLS_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "sharedobject.h"
|
||||
#include "unicode/dtfmtsym.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
class U_I18N_API SharedDateFormatSymbols : public SharedObject {
|
||||
public:
|
||||
SharedDateFormatSymbols(
|
||||
const Locale &loc, const char *type, UErrorCode &status)
|
||||
: dfs(loc, type, status) { }
|
||||
virtual ~SharedDateFormatSymbols();
|
||||
const DateFormatSymbols &get() const { return dfs; }
|
||||
private:
|
||||
DateFormatSymbols dfs;
|
||||
SharedDateFormatSymbols(const SharedDateFormatSymbols &);
|
||||
SharedDateFormatSymbols &operator=(const SharedDateFormatSymbols &);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
@ -394,7 +394,8 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
|
||||
fDateOverride.setToBogus();
|
||||
fTimeOverride.setToBogus();
|
||||
initializeBooleanAttributes();
|
||||
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
|
||||
initializeCalendar(NULL,fLocale,status);
|
||||
fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
|
||||
initialize(fLocale, status);
|
||||
initializeDefaultCentury();
|
||||
|
||||
@ -414,7 +415,8 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
|
||||
fDateOverride.setTo(override);
|
||||
fTimeOverride.setToBogus();
|
||||
initializeBooleanAttributes();
|
||||
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
|
||||
initializeCalendar(NULL,fLocale,status);
|
||||
fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
|
||||
initialize(fLocale, status);
|
||||
initializeDefaultCentury();
|
||||
|
||||
@ -438,7 +440,8 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
|
||||
fTimeOverride.setToBogus();
|
||||
initializeBooleanAttributes();
|
||||
|
||||
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
|
||||
initializeCalendar(NULL,fLocale,status);
|
||||
fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
|
||||
initialize(fLocale, status);
|
||||
initializeDefaultCentury();
|
||||
}
|
||||
@ -460,7 +463,8 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
|
||||
fTimeOverride.setToBogus();
|
||||
initializeBooleanAttributes();
|
||||
|
||||
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
|
||||
initializeCalendar(NULL,fLocale,status);
|
||||
fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
|
||||
initialize(fLocale, status);
|
||||
initializeDefaultCentury();
|
||||
|
||||
@ -550,7 +554,8 @@ SimpleDateFormat::SimpleDateFormat(const Locale& locale,
|
||||
{
|
||||
if (U_FAILURE(status)) return;
|
||||
initializeBooleanAttributes();
|
||||
initializeSymbols(fLocale, initializeCalendar(NULL, fLocale, status),status);
|
||||
initializeCalendar(NULL, fLocale, status);
|
||||
fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
|
||||
if (U_FAILURE(status))
|
||||
{
|
||||
status = U_ZERO_ERROR;
|
||||
@ -699,7 +704,7 @@ void SimpleDateFormat::construct(EStyle timeStyle,
|
||||
ures_getLocaleByType(dateTimePatterns, ULOC_ACTUAL_LOCALE, &status));
|
||||
|
||||
// create a symbols object from the locale
|
||||
initializeSymbols(locale,fCalendar, status);
|
||||
fSymbols = DateFormatSymbols::createForLocale(locale, status);
|
||||
if (U_FAILURE(status)) return;
|
||||
/* test for NULL */
|
||||
if (fSymbols == 0) {
|
||||
@ -870,28 +875,9 @@ SimpleDateFormat::initializeCalendar(TimeZone* adoptZone, const Locale& locale,
|
||||
if(!U_FAILURE(status)) {
|
||||
fCalendar = Calendar::createInstance(adoptZone?adoptZone:TimeZone::createDefault(), locale, status);
|
||||
}
|
||||
if (U_SUCCESS(status) && fCalendar == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return fCalendar;
|
||||
}
|
||||
|
||||
void
|
||||
SimpleDateFormat::initializeSymbols(const Locale& locale, Calendar* calendar, UErrorCode& status)
|
||||
{
|
||||
if(U_FAILURE(status)) {
|
||||
fSymbols = NULL;
|
||||
} else {
|
||||
// pass in calendar type - use NULL (default) if no calendar set (or err).
|
||||
fSymbols = new DateFormatSymbols(locale, calendar?calendar->getType() :NULL , status);
|
||||
// Null pointer check
|
||||
if (fSymbols == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimpleDateFormat::initialize(const Locale& locale,
|
||||
UErrorCode& status)
|
||||
@ -3517,10 +3503,16 @@ SimpleDateFormat::setTimeZoneFormat(const TimeZoneFormat& newTimeZoneFormat)
|
||||
void SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale calLocale(fLocale);
|
||||
calLocale.setKeywordValue("calendar", calendarToAdopt->getType(), status);
|
||||
DateFormatSymbols *newSymbols =
|
||||
DateFormatSymbols::createForLocale(calLocale, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
DateFormat::adoptCalendar(calendarToAdopt);
|
||||
delete fSymbols;
|
||||
fSymbols=NULL;
|
||||
initializeSymbols(fLocale, fCalendar, status); // we need new symbols
|
||||
fSymbols = newSymbols;
|
||||
initializeDefaultCentury(); // we need a new century (possibly)
|
||||
}
|
||||
|
||||
|
@ -2461,6 +2461,34 @@ private:
|
||||
* @return TRUE if a transition is found.
|
||||
*/
|
||||
UBool getImmediatePreviousZoneTransition(UDate base, UDate *transitionTime, UErrorCode& status) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new Calendar from a Locale for the cache.
|
||||
* This method does not set the time or timezone in returned calendar.
|
||||
* @param locale the locale.
|
||||
* @param status any error returned here.
|
||||
* @return the new Calendar object with no time or timezone set.
|
||||
* @internal For ICU use only.
|
||||
*/
|
||||
static Calendar U_EXPORT2 *makeInstance(
|
||||
const Locale &locale, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Get the calendar type for given locale.
|
||||
* @param locale the locale
|
||||
* @param typeBuffer calendar type returned here
|
||||
* @param typeBufferSize The size of typeBuffer in bytes. If the type
|
||||
* can't fit in the buffer, this method sets status to
|
||||
* U_BUFFER_OVERFLOW_ERROR
|
||||
* @param status error, if any, returned here.
|
||||
* @internal For ICU use only.
|
||||
*/
|
||||
static void U_EXPORT2 getCalendarTypeFromLocale(
|
||||
const Locale &locale,
|
||||
char *typeBuffer,
|
||||
int32_t typeBufferSize,
|
||||
UErrorCode &status);
|
||||
};
|
||||
|
||||
// -------------------------------------
|
||||
|
@ -902,6 +902,20 @@ private:
|
||||
* Returns TRUE if c (repeated count times) is the pattern character for a numeric field.
|
||||
*/
|
||||
static UBool U_EXPORT2 isNumericPatternChar(UChar c, int32_t count);
|
||||
public:
|
||||
/**
|
||||
* Gets a DateFormatSymbols by locale.
|
||||
* Unlike the constructors which always use gregorian calendar, this
|
||||
* method uses the calendar in the locale. If the locale contains no
|
||||
* explicit calendar, this method uses the default calendar for that
|
||||
* locale.
|
||||
* @param locale the locale.
|
||||
* @param status error returned here.
|
||||
* @return the new DateFormatSymbols which the caller owns.
|
||||
* @internal For ICU use only.
|
||||
*/
|
||||
static DateFormatSymbols * U_EXPORT2 createForLocale(
|
||||
const Locale &locale, UErrorCode &status);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -1310,14 +1310,6 @@ private:
|
||||
*/
|
||||
Calendar *initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* initializes fSymbols from parameters.
|
||||
* @param locale Locale of the symbols
|
||||
* @param calendar Alias to Calendar that will be used.
|
||||
* @param status Error code
|
||||
*/
|
||||
void initializeSymbols(const Locale& locale, Calendar* calendar, UErrorCode& status);
|
||||
|
||||
/**
|
||||
* Called by several of the constructors to load pattern data and formatting symbols
|
||||
* out of a resource bundle and initialize the locale based on it.
|
||||
|
@ -108,6 +108,9 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam
|
||||
TESTCASE_AUTO(TestCreateInstanceForSkeleton);
|
||||
TESTCASE_AUTO(TestCreateInstanceForSkeletonDefault);
|
||||
TESTCASE_AUTO(TestCreateInstanceForSkeletonWithCalendar);
|
||||
TESTCASE_AUTO(TestDFSCreateForLocaleNonGregorianLocale);
|
||||
TESTCASE_AUTO(TestDFSCreateForLocaleWithCalendarInLocale);
|
||||
TESTCASE_AUTO(TestChangeCalendar);
|
||||
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
@ -4686,6 +4689,63 @@ void DateFormatTest::TestCreateInstanceForSkeletonWithCalendar() {
|
||||
assertSuccess("", status);
|
||||
}
|
||||
|
||||
void DateFormatTest::TestDFSCreateForLocaleNonGregorianLocale() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale fa("fa");
|
||||
LocalPointer<DateFormatSymbols> sym(
|
||||
DateFormatSymbols::createForLocale(fa, status));
|
||||
if (!assertSuccess("", status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Farsi should default to the persian calendar, not gregorian
|
||||
int32_t count;
|
||||
const UnicodeString *months = sym->getShortMonths(count);
|
||||
|
||||
// First persian month.
|
||||
UnicodeString expected("\\u0641\\u0631\\u0648\\u0631\\u062f\\u06cc\\u0646");
|
||||
assertEquals("", expected.unescape(), months[0]);
|
||||
}
|
||||
|
||||
void DateFormatTest::TestDFSCreateForLocaleWithCalendarInLocale() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale en_heb("en@calendar=hebrew");
|
||||
LocalPointer<DateFormatSymbols> sym(
|
||||
DateFormatSymbols::createForLocale(en_heb, status));
|
||||
if (!assertSuccess("", status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We should get the months of the hebrew calendar, not the gregorian
|
||||
// calendar.
|
||||
int32_t count;
|
||||
const UnicodeString *months = sym->getShortMonths(count);
|
||||
|
||||
// First hebrew month.
|
||||
UnicodeString expected("Tishri");
|
||||
assertEquals("", expected, months[0]);
|
||||
}
|
||||
|
||||
void DateFormatTest::TestChangeCalendar() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale en("en");
|
||||
Locale en_heb("en@calendar=hebrew");
|
||||
LocalPointer<DateFormat> fmt(
|
||||
DateFormat::createInstanceForSkeleton("yMMMd", en, status));
|
||||
if (!assertSuccess("", status)) {
|
||||
return;
|
||||
}
|
||||
fmt->adoptCalendar(Calendar::createInstance(en_heb, status));
|
||||
if (!assertSuccess("", status)) {
|
||||
return;
|
||||
}
|
||||
UnicodeString result;
|
||||
FieldPosition pos(0);
|
||||
fmt->format(date(98, 5-1, 25), result, pos);
|
||||
assertEquals("format yMMMd", "Iyar 29, 5758", result);
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
||||
//eof
|
||||
|
@ -244,6 +244,9 @@ public:
|
||||
void TestCreateInstanceForSkeleton();
|
||||
void TestCreateInstanceForSkeletonDefault();
|
||||
void TestCreateInstanceForSkeletonWithCalendar();
|
||||
void TestDFSCreateForLocaleNonGregorianLocale();
|
||||
void TestDFSCreateForLocaleWithCalendarInLocale();
|
||||
void TestChangeCalendar();
|
||||
|
||||
private:
|
||||
UBool showParse(DateFormat &format, const UnicodeString &formattedString);
|
||||
|
Loading…
Reference in New Issue
Block a user