Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICU-23001 Add DataLocaleInformation interface #3335

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 9 additions & 20 deletions icu4c/source/common/brkiter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,8 @@ BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &st

// If there is a result, set the valid locale and actual locale, and the kind
if (U_SUCCESS(status) && result != nullptr) {
U_LOCALE_BASED(locBased, *(BreakIterator*)result);

locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status),
actual.data(), status);
result->setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status),
actual.data());
LocaleBased::setLocaleID(loc.getName(), result->requestLocale, status);
}

Expand Down Expand Up @@ -207,19 +205,17 @@ BreakIterator::BreakIterator()
{
}

BreakIterator::BreakIterator(const BreakIterator &other) : UObject(other) {
BreakIterator::BreakIterator(const BreakIterator &other) : UObject(other), DataLocaleInformation(other) {
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) {
DataLocaleInformation::operator=(other);
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));
}
Expand All @@ -228,8 +224,6 @@ BreakIterator &BreakIterator::operator =(const BreakIterator &other) {

BreakIterator::~BreakIterator()
{
delete validLocale;
delete actualLocale;
delete requestLocale;
}

Expand Down Expand Up @@ -398,8 +392,7 @@ BreakIterator::createInstance(const Locale& loc, int32_t kind, UErrorCode& statu
// THIS LONG is a sign of bad code -- so the action item is to
// 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(), status);
result->setLocaleIDs(actualLoc.getName(), actualLoc.getName());
}
return result;
}
Expand Down Expand Up @@ -509,7 +502,7 @@ BreakIterator::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
return requestLocale == nullptr ?
Locale::getRoot() : Locale(requestLocale->data());
}
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
return DataLocaleInformation::getLocale(type, status);
}

const char *
Expand All @@ -520,10 +513,9 @@ BreakIterator::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
if (type == ULOC_REQUESTED_LOCALE) {
return requestLocale == nullptr ? "" : requestLocale->data();
}
return LocaleBased::getLocaleID(validLocale, actualLocale, type, status);
return DataLocaleInformation::getLocaleID(type, status);
}


// This implementation of getRuleStatus is a do-nothing stub, here to
// provide a default implementation for any derived BreakIterator classes that
// do not implement it themselves.
Expand All @@ -547,10 +539,7 @@ 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.getName(), actual.getName(), status);
U_ASSERT(U_SUCCESS(status));
setLocaleIDs(valid.getName(), actual.getName());
}

U_NAMESPACE_END
Expand Down
37 changes: 37 additions & 0 deletions icu4c/source/common/locid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "uniquecharstr.h"
#include "ustr_imp.h"
#include "uvector.h"
#include "locbased.h"

U_NAMESPACE_BEGIN

Expand Down Expand Up @@ -2729,5 +2730,41 @@ Locale::getBaseName() const {

Locale::Iterator::~Iterator() = default;

DataLocaleInformation::DataLocaleInformation(const DataLocaleInformation& other) {
UErrorCode status = U_ZERO_ERROR;
actualLocale = other.actualLocale == nullptr ? nullptr : new CharString(*other.actualLocale, status);
validLocale = other.validLocale == nullptr ? nullptr : new CharString(*other.validLocale, status);
U_ASSERT(U_SUCCESS(status));
}
DataLocaleInformation::~DataLocaleInformation() {
delete actualLocale;
delete validLocale;
}

Locale DataLocaleInformation::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}

const char* DataLocaleInformation::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
return LocaleBased::getLocaleID(validLocale, actualLocale, type, status);
}

void DataLocaleInformation::setLocaleIDs(const char* valid, const char* actual) {
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(valid, actual, status);
U_ASSERT(U_SUCCESS(status));
}

DataLocaleInformation& DataLocaleInformation::operator=(const DataLocaleInformation& other) {
delete actualLocale;
delete validLocale;
UErrorCode status = U_ZERO_ERROR;
actualLocale = other.actualLocale == nullptr ? nullptr : new CharString(*other.actualLocale, status);
validLocale = other.validLocale == nullptr ? nullptr : new CharString(*other.validLocale, status);
U_ASSERT(U_SUCCESS(status));
return *this;
}

//eof
U_NAMESPACE_END
6 changes: 2 additions & 4 deletions icu4c/source/common/unicode/brkiter.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class CharString;
* and in the sample program icu/source/samples/break/break.cpp
*
*/
class U_COMMON_API BreakIterator : public UObject {
class U_COMMON_API BreakIterator : public UObject , public DataLocaleInformation {
public:
/**
* destructor
Expand Down Expand Up @@ -584,7 +584,7 @@ class U_COMMON_API BreakIterator : public UObject {
* actual locale.
* @stable ICU 2.8
*/
Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const override;

#ifndef U_HIDE_INTERNAL_API
/** Get the locale for this break iterator object. You can choose between valid and actual locale.
Expand Down Expand Up @@ -648,8 +648,6 @@ class U_COMMON_API BreakIterator : public UObject {
private:

/** @internal (private) */
CharString* actualLocale = nullptr;
CharString* validLocale = nullptr;
CharString* requestLocale = nullptr;
};

Expand Down
58 changes: 58 additions & 0 deletions icu4c/source/common/unicode/locid.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void U_CALLCONV locale_available_init(); /**< @internal */

class StringEnumeration;
class UnicodeString;
class CharString;

/**
* A <code>Locale</code> object represents a specific geographical, political,
Expand Down Expand Up @@ -1283,6 +1284,63 @@ Locale::isBogus() const {
return fIsBogus;
}

/**
* <code>DataLocaleInformation</code> is an abstract base class for objects
* that perform getLocale operations to query locale data resolution.
*/
class U_COMMON_API DataLocaleInformation : public UMemory {
public:
DataLocaleInformation() = default;

/**
* Initializes a DataLocaleInformation object from another
* DataLocaleInformation object.
*
* @param other The DataLocaleInformation object being copied in.
*/
DataLocaleInformation(const DataLocaleInformation& other);

virtual ~DataLocaleInformation();

/**
* Set the locale meta-data for the service object wrapped by this
* object. If either parameter is zero, it is ignored.
* @param valid the ID of the valid locale
* @param actual the ID of the actual locale
*/
virtual void setLocaleIDs(const char* valid, const char* actual);

/** Get the locale for this object. You can choose between valid and actual locale.
* @param type type of the locale we're looking for (valid or actual)
* @param status error code for the operation
* @return the locale
*/
virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;

#ifndef U_HIDE_INTERNAL_API
/** Get the locale for this object. You can choose between valid and actual locale.
* @param type type of the locale we're looking for (valid or actual)
* @param status error code for the operation
* @return the locale
* @internal
*/
const char* getLocaleID(ULocDataLocaleType type, UErrorCode &status) const;
#endif /* U_HIDE_INTERNAL_API */

/**
* Replaces the entire contents of *this with the specified value.
*
* @param other The DataLocaleInformation object being copied in.
* @return *this
*/
DataLocaleInformation& operator=(const DataLocaleInformation& other);


private:
CharString* validLocale = nullptr;
CharString* actualLocale = nullptr;
};

U_NAMESPACE_END

#endif /* U_SHOW_CPLUSPLUS_API */
Expand Down
24 changes: 4 additions & 20 deletions icu4c/source/i18n/calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,14 +774,12 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
Calendar::~Calendar()
{
delete fZone;
delete actualLocale;
delete validLocale;
}

// -------------------------------------

Calendar::Calendar(const Calendar &source)
: UObject(source)
: UObject(source), DataLocaleInformation(source)
{
*this = source;
}
Expand All @@ -792,6 +790,7 @@ Calendar &
Calendar::operator=(const Calendar &right)
{
if (this != &right) {
DataLocaleInformation::operator=(right);
uprv_arrayCopy(right.fFields, fFields, UCAL_FIELD_COUNT);
uprv_arrayCopy(right.fStamp, fStamp, UCAL_FIELD_COUNT);
fTime = right.fTime;
Expand All @@ -814,10 +813,6 @@ Calendar::operator=(const Calendar &right)
fWeekendCease = right.fWeekendCease;
fWeekendCeaseMillis = right.fWeekendCeaseMillis;
fNextStamp = right.fNextStamp;
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(right.validLocale, right.actualLocale, status);
U_ASSERT(U_SUCCESS(status));
}

return *this;
Expand Down Expand Up @@ -4109,9 +4104,8 @@ 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), status);
setLocaleIDs(ures_getLocaleByType(monthNames.getAlias(), ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(monthNames.getAlias(), ULOC_ACTUAL_LOCALE, &status));
} else {
status = U_USING_FALLBACK_WARNING;
return;
Expand Down Expand Up @@ -4197,16 +4191,6 @@ Calendar::updateTime(UErrorCode& status)
fAreFieldsVirtuallySet = false;
}

Locale
Calendar::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}

const char *
Calendar::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
return LocaleBased::getLocaleID(validLocale, actualLocale, type, status);
}

void
Calendar::recalculateStamp() {
int32_t index;
Expand Down
23 changes: 4 additions & 19 deletions icu4c/source/i18n/dtfmtsym.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)
}

DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
: UObject(other)
: UObject(other), DataLocaleInformation(other)
{
copyData(other);
}
Expand Down Expand Up @@ -400,10 +400,6 @@ DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
*/
void
DateFormatSymbols::copyData(const DateFormatSymbols& other) {
UErrorCode status = U_ZERO_ERROR;
U_LOCALE_BASED(locBased, *this);
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);
Expand Down Expand Up @@ -487,6 +483,7 @@ DateFormatSymbols::copyData(const DateFormatSymbols& other) {
DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
{
if (this == &other) { return *this; } // self-assignment: no-op
DataLocaleInformation::operator=(other);
dispose();
copyData(other);

Expand All @@ -496,8 +493,6 @@ DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
DateFormatSymbols::~DateFormatSymbols()
{
dispose();
delete actualLocale;
delete validLocale;
}

void DateFormatSymbols::dispose()
Expand Down Expand Up @@ -537,10 +532,6 @@ void DateFormatSymbols::dispose()
delete[] fStandaloneWideDayPeriods;
delete[] fStandaloneNarrowDayPeriods;

delete actualLocale;
actualLocale = nullptr;
delete validLocale;
validLocale = nullptr;
disposeZoneStrings();
}

Expand Down Expand Up @@ -2302,12 +2293,11 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
}
}

U_LOCALE_BASED(locBased, *this);
// 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(ures_getLocaleByType(cb.getAlias(), ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(cb.getAlias(), ULOC_ACTUAL_LOCALE, &status), status);
setLocaleIDs(ures_getLocaleByType(cb.getAlias(), ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(cb.getAlias(), ULOC_ACTUAL_LOCALE, &status));

// Load eras
initField(&fEras, fErasCount, calendarSink, buildResourcePath(path, gErasTag, gNamesAbbrTag, status), status);
Expand Down Expand Up @@ -2531,11 +2521,6 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
}
}

Locale
DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
return LocaleBased::getLocale(validLocale, actualLocale, type, status);
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */
Expand Down
Loading
Loading