ICU-23000 Replace CharString for LocaleBased

See #3321
This commit is contained in:
Frank Yung-Fong Tang 2025-01-04 03:58:59 +00:00
parent 93ce388619
commit 4c3622f218
14 changed files with 206 additions and 118 deletions

View file

@ -59,7 +59,7 @@ BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &st
{
char fnbuff[256];
char ext[4]={'\0'};
CharString actualLocale;
CharString actual;
int32_t size;
const char16_t* brkfname = nullptr;
UResourceBundle brkRulesStack;
@ -94,7 +94,7 @@ BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &st
// Use the string if we found it
if (U_SUCCESS(status) && brkfname) {
actualLocale.append(ures_getLocaleInternal(brkName, &status), -1, status);
actual.append(ures_getLocaleInternal(brkName, &status), -1, status);
char16_t* extStart=u_strchr(brkfname, 0x002e);
int len = 0;
@ -123,10 +123,9 @@ BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &st
if (U_SUCCESS(status) && result != nullptr) {
U_LOCALE_BASED(locBased, *(BreakIterator*)result);
locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status),
actualLocale.data());
uprv_strncpy(result->requestLocale, loc.getName(), ULOC_FULLNAME_CAPACITY);
result->requestLocale[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status),
actual.data(), status);
LocaleBased::setLocaleID(loc.getName(), result->requestLocale, status);
}
ures_close(b);
@ -206,26 +205,32 @@ BreakIterator::getAvailableLocales(int32_t& count)
BreakIterator::BreakIterator()
{
*validLocale = *actualLocale = *requestLocale = 0;
}
BreakIterator::BreakIterator(const BreakIterator &other) : UObject(other) {
uprv_strncpy(actualLocale, other.actualLocale, sizeof(actualLocale));
uprv_strncpy(validLocale, other.validLocale, sizeof(validLocale));
uprv_strncpy(requestLocale, other.requestLocale, sizeof(requestLocale));
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(other.validLocale, other.actualLocale, status);
LocaleBased::setLocaleID(other.requestLocale, requestLocale, status);
U_ASSERT(U_SUCCESS(status));
}
BreakIterator &BreakIterator::operator =(const BreakIterator &other) {
if (this != &other) {
uprv_strncpy(actualLocale, other.actualLocale, sizeof(actualLocale));
uprv_strncpy(validLocale, other.validLocale, sizeof(validLocale));
uprv_strncpy(requestLocale, other.requestLocale, sizeof(requestLocale));
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(other.validLocale, other.actualLocale, status);
LocaleBased::setLocaleID(other.requestLocale, requestLocale, status);
U_ASSERT(U_SUCCESS(status));
}
return *this;
}
BreakIterator::~BreakIterator()
{
delete validLocale;
delete actualLocale;
delete requestLocale;
}
// ------------------------------------------
@ -394,7 +399,7 @@ BreakIterator::createInstance(const Locale& loc, int32_t kind, UErrorCode& statu
// revisit this in ICU 3.0 and clean it up/fix it/remove it.
if (U_SUCCESS(status) && (result != nullptr) && *actualLoc.getName() != 0) {
U_LOCALE_BASED(locBased, *result);
locBased.setLocaleIDs(actualLoc.getName(), actualLoc.getName());
locBased.setLocaleIDs(actualLoc.getName(), actualLoc.getName(), status);
}
return result;
}
@ -488,6 +493,7 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
}
if (U_FAILURE(status)) {
delete result;
return nullptr;
}
@ -496,20 +502,25 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
Locale
BreakIterator::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
if (type == ULOC_REQUESTED_LOCALE) {
return {requestLocale};
if (U_FAILURE(status)) {
return Locale::getRoot();
}
U_LOCALE_BASED(locBased, *this);
return locBased.getLocale(type, status);
if (type == ULOC_REQUESTED_LOCALE) {
return requestLocale == nullptr ?
Locale::getRoot() : Locale(requestLocale->data());
}
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}
const char *
BreakIterator::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
if (type == ULOC_REQUESTED_LOCALE) {
return requestLocale;
if (U_FAILURE(status)) {
return nullptr;
}
U_LOCALE_BASED(locBased, *this);
return locBased.getLocaleID(type, status);
if (type == ULOC_REQUESTED_LOCALE) {
return requestLocale == nullptr ? "" : requestLocale->data();
}
return LocaleBased::getLocaleID(validLocale, actualLocale, type, status);
}
@ -536,8 +547,10 @@ int32_t BreakIterator::getRuleStatusVec(int32_t *fillInVec, int32_t capacity, UE
}
BreakIterator::BreakIterator (const Locale& valid, const Locale& actual) {
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, (*this));
locBased.setLocaleIDs(valid, actual);
locBased.setLocaleIDs(valid.getName(), actual.getName(), status);
U_ASSERT(U_SUCCESS(status));
}
U_NAMESPACE_END

View file

@ -70,6 +70,15 @@ CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
return *this;
}
CharString &CharString::copyFrom(StringPiece s, UErrorCode &errorCode) {
if (U_FAILURE(errorCode)) {
return *this;
}
len = 0;
append(s, errorCode);
return *this;
}
int32_t CharString::lastIndexOf(char c) const {
for(int32_t i=len; i>0;) {
if(buffer[--i]==c) {

View file

@ -74,6 +74,7 @@ public:
* use a UErrorCode where memory allocations might be needed.
*/
CharString &copyFrom(const CharString &other, UErrorCode &errorCode);
CharString &copyFrom(StringPiece s, UErrorCode &errorCode);
UBool isEmpty() const { return len==0; }
int32_t length() const { return len; }

View file

@ -12,44 +12,84 @@
*/
#include "locbased.h"
#include "cstring.h"
#include "charstr.h"
U_NAMESPACE_BEGIN
Locale LocaleBased::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
const char* id = getLocaleID(type, status);
Locale LocaleBased::getLocale(const CharString* valid, const CharString* actual,
ULocDataLocaleType type, UErrorCode& status) {
const char* id = getLocaleID(valid, actual, type, status);
return Locale(id != nullptr ? id : "");
}
const char* LocaleBased::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
const char* LocaleBased::getLocaleID(const CharString* valid, const CharString* actual,
ULocDataLocaleType type, UErrorCode& status) {
if (U_FAILURE(status)) {
return nullptr;
}
switch(type) {
case ULOC_VALID_LOCALE:
return valid;
return valid == nullptr ? "" : valid->data();
case ULOC_ACTUAL_LOCALE:
return actual;
return actual == nullptr ? "" : actual->data();
default:
status = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
}
void LocaleBased::setLocaleIDs(const char* validID, const char* actualID) {
if (validID != nullptr) {
uprv_strncpy(valid, validID, ULOC_FULLNAME_CAPACITY);
valid[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
}
if (actualID != nullptr) {
uprv_strncpy(actual, actualID, ULOC_FULLNAME_CAPACITY);
actual[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
void LocaleBased::setLocaleIDs(const CharString* validID, const CharString* actualID, UErrorCode& status) {
setValidLocaleID(validID, status);
setActualLocaleID(actualID,status);
}
void LocaleBased::setLocaleIDs(const char* validID, const char* actualID, UErrorCode& status) {
setValidLocaleID(validID, status);
setActualLocaleID(actualID,status);
}
void LocaleBased::setLocaleID(const char* id, CharString*& dest, UErrorCode& status) {
if (U_FAILURE(status)) { return; }
if (id == nullptr || *id == 0) {
delete dest;
dest = nullptr;
} else {
if (dest == nullptr) {
dest = new CharString(id, status);
if (dest == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
} else {
dest->copyFrom(id, status);
}
}
}
void LocaleBased::setLocaleIDs(const Locale& validID, const Locale& actualID) {
uprv_strcpy(valid, validID.getName());
uprv_strcpy(actual, actualID.getName());
void LocaleBased::setLocaleID(const CharString* id, CharString*& dest, UErrorCode& status) {
if (U_FAILURE(status)) { return; }
if (id == nullptr || id->isEmpty()) {
delete dest;
dest = nullptr;
} else {
if (dest == nullptr) {
dest = new CharString(*id, status);
if (dest == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
} else {
dest->copyFrom(*id, status);
}
}
}
bool LocaleBased::equalIDs(const CharString* left, const CharString* right) {
// true if both are nullptr
if (left == nullptr && right == nullptr) return true;
// false if only one is nullptr
if (left == nullptr || right == nullptr) return false;
return *left == *right;
}
U_NAMESPACE_END

View file

@ -19,13 +19,14 @@
/**
* Macro to declare a locale LocaleBased wrapper object for the given
* object, which must have two members named `validLocale' and
* `actualLocale' of size ULOC_FULLNAME_CAPACITY
* `actualLocale' of which are pointers to the internal icu::CharString.
*/
#define U_LOCALE_BASED(varname, objname) \
LocaleBased varname((objname).validLocale, (objname).actualLocale)
U_NAMESPACE_BEGIN
class CharString;
/**
* A utility class that unifies the implementation of getLocale() by
* various ICU services. This class is likely to be removed in the
@ -41,33 +42,35 @@ class U_COMMON_API LocaleBased : public UMemory {
* Construct a LocaleBased wrapper around the two pointers. These
* will be aliased for the lifetime of this object.
*/
inline LocaleBased(char* validAlias, char* actualAlias);
/**
* Construct a LocaleBased wrapper around the two const pointers.
* These will be aliased for the lifetime of this object.
*/
inline LocaleBased(const char* validAlias, const char* actualAlias);
inline LocaleBased(CharString*& validAlias, CharString*& actualAlias);
/**
* Return locale meta-data for the service object wrapped by this
* object. Either the valid or the actual locale may be
* retrieved.
* @param valid The valid locale.
* @param actual The actual locale.
* @param type either ULOC_VALID_LOCALE or ULOC_ACTUAL_LOCALE
* @param status input-output error code
* @return the indicated locale
*/
Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
static Locale getLocale(
const CharString* valid, const CharString* actual,
ULocDataLocaleType type, UErrorCode& status);
/**
* Return the locale ID for the service object wrapped by this
* object. Either the valid or the actual locale may be
* retrieved.
* @param valid The valid locale.
* @param actual The actual locale.
* @param type either ULOC_VALID_LOCALE or ULOC_ACTUAL_LOCALE
* @param status input-output error code
* @return the indicated locale ID
*/
const char* getLocaleID(ULocDataLocaleType type, UErrorCode& status) const;
static const char* getLocaleID(
const CharString* valid, const CharString* actual,
ULocDataLocaleType type, UErrorCode& status);
/**
* Set the locale meta-data for the service object wrapped by this
@ -75,31 +78,40 @@ class U_COMMON_API LocaleBased : public UMemory {
* @param valid the ID of the valid locale
* @param actual the ID of the actual locale
*/
void setLocaleIDs(const char* valid, const char* actual);
void setLocaleIDs(const char* valid, const char* actual, UErrorCode& status);
void setLocaleIDs(const CharString* valid, const CharString* actual, UErrorCode& status);
/**
* Set the locale meta-data for the service object wrapped by this
* object.
* @param valid the ID of the valid locale
* @param actual the ID of the actual locale
*/
void setLocaleIDs(const Locale& valid, const Locale& actual);
static void setLocaleID(const char* id, CharString*& dest, UErrorCode& status);
static void setLocaleID(const CharString* id, CharString*& dest, UErrorCode& status);
static bool equalIDs(const CharString* left, const CharString* right);
private:
char* valid;
char* actual;
void setValidLocaleID(const CharString* id, UErrorCode& status);
void setActualLocaleID(const CharString* id, UErrorCode& status);
void setValidLocaleID(const char* id, UErrorCode& status);
void setActualLocaleID(const char* id, UErrorCode& status);
CharString*& valid;
CharString*& actual;
};
inline LocaleBased::LocaleBased(char* validAlias, char* actualAlias) :
inline LocaleBased::LocaleBased(CharString*& validAlias, CharString*& actualAlias) :
valid(validAlias), actual(actualAlias) {
}
inline LocaleBased::LocaleBased(const char* validAlias,
const char* actualAlias) :
// ugh: cast away const
valid(const_cast<char*>(validAlias)), actual(const_cast<char*>(actualAlias)) {
inline void LocaleBased::setValidLocaleID(const CharString* id, UErrorCode& status) {
setLocaleID(id, valid, status);
}
inline void LocaleBased::setActualLocaleID(const CharString* id, UErrorCode& status) {
setLocaleID(id, actual, status);
}
inline void LocaleBased::setValidLocaleID(const char* id, UErrorCode& status) {
setLocaleID(id, valid, status);
}
inline void LocaleBased::setActualLocaleID(const char* id, UErrorCode& status) {
setLocaleID(id, actual, status);
}
U_NAMESPACE_END

View file

@ -58,6 +58,8 @@ U_NAMESPACE_END
U_NAMESPACE_BEGIN
class CharString;
/**
* The BreakIterator class implements methods for finding the location
* of boundaries in text. BreakIterator is an abstract base class.
@ -646,9 +648,9 @@ protected:
private:
/** @internal (private) */
char actualLocale[ULOC_FULLNAME_CAPACITY];
char validLocale[ULOC_FULLNAME_CAPACITY];
char requestLocale[ULOC_FULLNAME_CAPACITY];
CharString* actualLocale = nullptr;
CharString* validLocale = nullptr;
CharString* requestLocale = nullptr;
};
#ifndef U_HIDE_DEPRECATED_API

View file

@ -707,8 +707,6 @@ fZone(nullptr),
fRepeatedWallTime(UCAL_WALLTIME_LAST),
fSkippedWallTime(UCAL_WALLTIME_LAST)
{
validLocale[0] = 0;
actualLocale[0] = 0;
clear();
if (U_FAILURE(success)) {
return;
@ -722,7 +720,7 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
// -------------------------------------
Calendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
Calendar::Calendar(TimeZone* adoptZone, const Locale& aLocale, UErrorCode& success)
: UObject(),
fIsTimeSet(false),
fAreFieldsSet(false),
@ -735,13 +733,11 @@ fZone(nullptr),
fRepeatedWallTime(UCAL_WALLTIME_LAST),
fSkippedWallTime(UCAL_WALLTIME_LAST)
{
validLocale[0] = 0;
actualLocale[0] = 0;
LocalPointer<TimeZone> zone(adoptZone, success);
if (U_FAILURE(success)) {
delete zone;
return;
}
if (zone == nullptr) {
if (zone.isNull()) {
#if defined (U_DEBUG_CAL)
fprintf(stderr, "%s:%d: ILLEGAL ARG because timezone cannot be 0\n",
__FILE__, __LINE__);
@ -751,7 +747,7 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
}
clear();
fZone = zone;
fZone = zone.orphan();
setWeekData(aLocale, nullptr, success);
}
@ -770,8 +766,6 @@ fZone(nullptr),
fRepeatedWallTime(UCAL_WALLTIME_LAST),
fSkippedWallTime(UCAL_WALLTIME_LAST)
{
validLocale[0] = 0;
actualLocale[0] = 0;
if (U_FAILURE(success)) {
return;
}
@ -779,6 +773,7 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
fZone = zone.clone();
if (fZone == nullptr) {
success = U_MEMORY_ALLOCATION_ERROR;
return;
}
setWeekData(aLocale, nullptr, success);
}
@ -788,6 +783,8 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
Calendar::~Calendar()
{
delete fZone;
delete actualLocale;
delete validLocale;
}
// -------------------------------------
@ -827,10 +824,10 @@ Calendar::operator=(const Calendar &right)
fWeekendCease = right.fWeekendCease;
fWeekendCeaseMillis = right.fWeekendCeaseMillis;
fNextStamp = right.fNextStamp;
uprv_strncpy(validLocale, right.validLocale, sizeof(validLocale)-1);
validLocale[sizeof(validLocale)-1] = 0;
uprv_strncpy(actualLocale, right.actualLocale, sizeof(actualLocale)-1);
actualLocale[sizeof(validLocale)-1] = 0;
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(right.validLocale, right.actualLocale, status);
U_ASSERT(U_SUCCESS(status));
}
return *this;
@ -4129,7 +4126,7 @@ Calendar::setWeekData(const Locale& desiredLocale, const char *type, UErrorCode&
if (U_SUCCESS(status)) {
U_LOCALE_BASED(locBased,*this);
locBased.setLocaleIDs(ures_getLocaleByType(monthNames.getAlias(), ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(monthNames.getAlias(), ULOC_ACTUAL_LOCALE, &status));
ures_getLocaleByType(monthNames.getAlias(), ULOC_ACTUAL_LOCALE, &status), status);
} else {
status = U_USING_FALLBACK_WARNING;
return;
@ -4217,14 +4214,12 @@ Calendar::updateTime(UErrorCode& status)
Locale
Calendar::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
U_LOCALE_BASED(locBased, *this);
return locBased.getLocale(type, status);
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}
const char *
Calendar::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
U_LOCALE_BASED(locBased, *this);
return locBased.getLocaleID(type, status);
return LocaleBased::getLocaleID(validLocale, actualLocale, type, status);
}
void

View file

@ -118,7 +118,6 @@ DecimalFormatSymbols::DecimalFormatSymbols(const Locale& loc, const NumberingSys
DecimalFormatSymbols::DecimalFormatSymbols()
: UObject(), locale(Locale::getRoot()) {
*validLocale = *actualLocale = 0;
initialize();
}
@ -136,6 +135,8 @@ DecimalFormatSymbols::createWithLastResortData(UErrorCode& status) {
DecimalFormatSymbols::~DecimalFormatSymbols()
{
delete actualLocale;
delete validLocale;
}
// -------------------------------------
@ -163,8 +164,12 @@ DecimalFormatSymbols::operator=(const DecimalFormatSymbols& rhs)
currencySpcAfterSym[i].fastCopyFrom(rhs.currencySpcAfterSym[i]);
}
locale = rhs.locale;
uprv_strcpy(validLocale, rhs.validLocale);
uprv_strcpy(actualLocale, rhs.actualLocale);
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(rhs.validLocale, rhs.actualLocale, status);
U_ASSERT(U_SUCCESS(status));
fIsCustomCurrencySymbol = rhs.fIsCustomCurrencySymbol;
fIsCustomIntlCurrencySymbol = rhs.fIsCustomIntlCurrencySymbol;
fCodePointZero = rhs.fCodePointZero;
@ -203,8 +208,8 @@ DecimalFormatSymbols::operator==(const DecimalFormatSymbols& that) const
}
// No need to check fCodePointZero since it is based on fSymbols
return locale == that.locale &&
uprv_strcmp(validLocale, that.validLocale) == 0 &&
uprv_strcmp(actualLocale, that.actualLocale) == 0;
LocaleBased::equalIDs(actualLocale, that.actualLocale) &&
LocaleBased::equalIDs(validLocale, that.validLocale);
}
// -------------------------------------
@ -353,7 +358,6 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
UBool useLastResortData, const NumberingSystem* ns)
{
if (U_FAILURE(status)) { return; }
*validLocale = *actualLocale = 0;
// First initialize all the symbols to the fallbacks for anything we can't find
initialize();
@ -409,7 +413,8 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(
numberElementsRes.getAlias(),
ULOC_ACTUAL_LOCALE, &status));
ULOC_ACTUAL_LOCALE, &status),
status);
// Now load the rest of the data from the data sink.
// Start with loading this nsName if it is not Latin.
@ -568,8 +573,7 @@ void DecimalFormatSymbols::setCurrency(const char16_t* currency, UErrorCode& sta
Locale
DecimalFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
U_LOCALE_BASED(locBased, *this);
return locBased.getLocale(type, status);
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}
const UnicodeString&

View file

@ -402,9 +402,8 @@ void
DateFormatSymbols::copyData(const DateFormatSymbols& other) {
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(
other.getLocale(ULOC_VALID_LOCALE, status),
other.getLocale(ULOC_ACTUAL_LOCALE, status));
locBased.setLocaleIDs(other.validLocale, other.actualLocale, status);
U_ASSERT(U_SUCCESS(status));
assignArray(fEras, fErasCount, other.fEras, other.fErasCount);
assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);
assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount);
@ -497,6 +496,8 @@ DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
DateFormatSymbols::~DateFormatSymbols()
{
dispose();
delete actualLocale;
delete validLocale;
}
void DateFormatSymbols::dispose()
@ -536,6 +537,10 @@ void DateFormatSymbols::dispose()
delete[] fStandaloneWideDayPeriods;
delete[] fStandaloneNarrowDayPeriods;
delete actualLocale;
actualLocale = nullptr;
delete validLocale;
validLocale = nullptr;
disposeZoneStrings();
}
@ -2302,7 +2307,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
// of it that we need except for the time-zone and localized-pattern data, which
// are stored in a separate file
locBased.setLocaleIDs(ures_getLocaleByType(cb.getAlias(), ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(cb.getAlias(), ULOC_ACTUAL_LOCALE, &status));
ures_getLocaleByType(cb.getAlias(), ULOC_ACTUAL_LOCALE, &status), status);
// Load eras
initField(&fEras, fErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesAbbrTag, status), status);
@ -2528,8 +2533,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
Locale
DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
U_LOCALE_BASED(locBased, *this);
return locBased.getLocale(type, status);
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}
U_NAMESPACE_END

View file

@ -24,6 +24,7 @@
#include "utypeinfo.h" // for 'typeid' to work
#include "unicode/utypes.h"
#include "charstr.h"
#ifndef U_I18N_IMPLEMENTATION
#error U_I18N_IMPLEMENTATION not set - must be set for all ICU source files in i18n/ - see https://unicode-org.github.io/icu/userguide/howtouseicu
@ -72,13 +73,14 @@ FieldPosition::clone() const {
Format::Format()
: UObject()
{
*validLocale = *actualLocale = 0;
}
// -------------------------------------
Format::~Format()
{
delete actualLocale;
delete validLocale;
}
// -------------------------------------
@ -97,8 +99,10 @@ Format&
Format::operator=(const Format& that)
{
if (this != &that) {
uprv_strcpy(validLocale, that.validLocale);
uprv_strcpy(actualLocale, that.actualLocale);
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(that.validLocale, that.actualLocale, status);
U_ASSERT(U_SUCCESS(status));
}
return *this;
}
@ -196,20 +200,20 @@ void Format::syntaxError(const UnicodeString& pattern,
Locale
Format::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
U_LOCALE_BASED(locBased, *this);
return locBased.getLocale(type, status);
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}
const char *
Format::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
U_LOCALE_BASED(locBased, *this);
return locBased.getLocaleID(type, status);
return LocaleBased::getLocaleID(validLocale,actualLocale, type, status);
}
void
Format::setLocaleIDs(const char* valid, const char* actual) {
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(valid, actual);
UErrorCode status = U_ZERO_ERROR;
locBased.setLocaleIDs(valid, actual, status);
U_ASSERT(U_SUCCESS(status));
}
U_NAMESPACE_END

View file

@ -55,6 +55,7 @@ class ICUServiceFactory;
typedef int32_t UFieldResolutionTable[12][8];
class BasicTimeZone;
class CharString;
/**
* `Calendar` is an abstract base class for converting between
* a `UDate` object and a set of integer fields such as
@ -2342,8 +2343,8 @@ private:
#endif /* U_HIDE_INTERNAL_API */
private:
char validLocale[ULOC_FULLNAME_CAPACITY];
char actualLocale[ULOC_FULLNAME_CAPACITY];
CharString* validLocale = nullptr;
CharString* actualLocale = nullptr;
public:
#if !UCONFIG_NO_SERVICE

View file

@ -48,6 +48,7 @@
U_NAMESPACE_BEGIN
class CharString;
/**
* This class represents the set of symbols needed by DecimalFormat
* to format numbers. DecimalFormat creates for itself an instance of
@ -504,8 +505,8 @@ private:
Locale locale;
char actualLocale[ULOC_FULLNAME_CAPACITY];
char validLocale[ULOC_FULLNAME_CAPACITY];
CharString* actualLocale = nullptr;
CharString* validLocale = nullptr;
const char16_t* currPattern = nullptr;
UnicodeString currencySpcBeforeSym[UNUM_CURRENCY_SPACING_COUNT];

View file

@ -43,6 +43,7 @@ U_NAMESPACE_BEGIN
/* forward declaration */
class SimpleDateFormat;
class Hashtable;
class CharString;
/**
* DateFormatSymbols is a public class for encapsulating localizable date-time
@ -917,8 +918,8 @@ private:
/** valid/actual locale information
* these are always ICU locales, so the length should not be a problem
*/
char validLocale[ULOC_FULLNAME_CAPACITY];
char actualLocale[ULOC_FULLNAME_CAPACITY];
CharString* validLocale = nullptr;
CharString* actualLocale = nullptr;
DateFormatSymbols() = delete; // default constructor not implemented

View file

@ -45,6 +45,7 @@
U_NAMESPACE_BEGIN
class CharString;
/**
* Base class for all formats. This is an abstract base class which
* specifies the protocol for classes which convert other objects or
@ -297,8 +298,8 @@ protected:
UParseError& parseError);
private:
char actualLocale[ULOC_FULLNAME_CAPACITY];
char validLocale[ULOC_FULLNAME_CAPACITY];
CharString* actualLocale = nullptr;
CharString* validLocale = nullptr;
};
U_NAMESPACE_END