Skip to content

Commit 06f6ec0

Browse files
committed
ICU-20392 Simplify code by removing Locale::initBaseName().
Whatever the purpose of this helper function originally was, subsequent refactorings have now made it obsolete. It requires both less code and less processing to assign baseName together with the other data fields, instead of starting over and searching for the '@' character once again and possibly having to move payload from Nest to Heap.
1 parent 54baf6b commit 06f6ec0

File tree

2 files changed

+27
-81
lines changed

2 files changed

+27
-81
lines changed

icu4c/source/common/locid.cpp

Lines changed: 27 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,7 @@ Locale& Locale::init(StringPiece localeID, UBool canonicalize)
19571957
} else {
19581958
fieldLen[fieldIdx - 1] = length - static_cast<int32_t>(field[fieldIdx - 1] - fullName);
19591959
}
1960+
bool hasKeywords = at != nullptr && uprv_strchr(at + 1, '=') != nullptr;
19601961

19611962
if (fieldLen[0] >= ULOC_LANG_CAPACITY)
19621963
{
@@ -1987,9 +1988,14 @@ Locale& Locale::init(StringPiece localeID, UBool canonicalize)
19871988
if (fieldLen[variantField] > 0) {
19881989
/* We have a variant */
19891990
variantBegin = static_cast<int32_t>(field[variantField] - fullName);
1991+
} else if (hasKeywords) {
1992+
// The original computation of variantBegin leaves it equal to the length
1993+
// of fullName if there is no variant. It should instead be
1994+
// the length of the baseName.
1995+
variantBegin = static_cast<int32_t>(at - fullName);
19901996
}
19911997

1992-
if (Nest::fits(length, language, script, region)) {
1998+
if (!hasKeywords && Nest::fits(length, language, script, region)) {
19931999
U_ASSERT(fullName == nest.baseName);
19942000
U_ASSERT(fullNameBuffer.isEmpty());
19952001
nest.init(language, script, region, variantBegin);
@@ -2008,11 +2014,14 @@ Locale& Locale::init(StringPiece localeID, UBool canonicalize)
20082014
}
20092015
U_ASSERT(!fullNameBuffer.isEmpty());
20102016
heap->fullName = std::move(fullNameBuffer);
2011-
}
2012-
2013-
initBaseName(err);
2014-
if (U_FAILURE(err)) {
2015-
break;
2017+
if (hasKeywords) {
2018+
if (std::string_view::size_type baseNameLength = at - fullName; baseNameLength > 0) {
2019+
heap->baseName = {heap->fullName.data(), baseNameLength};
2020+
if (heap->baseName.isEmpty()) {
2021+
break; // error: out of memory
2022+
}
2023+
}
2024+
}
20162025
}
20172026

20182027
if (canonicalize) {
@@ -2040,77 +2049,6 @@ Locale& Locale::init(StringPiece localeID, UBool canonicalize)
20402049
return *this;
20412050
}
20422051

2043-
/*
2044-
* Set up the base name.
2045-
* If there are no key words, it's exactly the full name.
2046-
* If key words exist, it's the full name truncated at the '@' character.
2047-
* Need to set up both at init() and after setting a keyword.
2048-
*/
2049-
void
2050-
Locale::initBaseName(UErrorCode &status) {
2051-
if (U_FAILURE(status)) {
2052-
return;
2053-
}
2054-
U_ASSERT(!isBogus());
2055-
2056-
std::unique_ptr<Heap>* heap = std::get_if<std::unique_ptr<Heap>>(&payload);
2057-
if (heap != nullptr && *heap && !(*heap)->baseName.isEmpty()) {
2058-
return;
2059-
}
2060-
2061-
const char *fullName = getName();
2062-
const char *atPtr = uprv_strchr(fullName, '@');
2063-
const char *eqPtr = uprv_strchr(fullName, '=');
2064-
if (atPtr && eqPtr && atPtr < eqPtr) {
2065-
// Key words exist.
2066-
int32_t baseNameLength = static_cast<int32_t>(atPtr - fullName);
2067-
if (baseNameLength == 0) { return; }
2068-
2069-
if (heap == nullptr) {
2070-
// There are keywords, so the payload needs to be moved from Nest
2071-
// to Heap so that it can get a baseName.
2072-
const Nest* nest = std::get_if<Nest>(&payload);
2073-
U_ASSERT(nest != nullptr);
2074-
std::unique_ptr<Heap> copy = std::make_unique<Heap>(nest->language,
2075-
nest->script,
2076-
nest->region,
2077-
nest->variantBegin);
2078-
if (!copy) {
2079-
status = U_MEMORY_ALLOCATION_ERROR;
2080-
setToBogus();
2081-
return;
2082-
}
2083-
copy->fullName = fullName;
2084-
if (copy->fullName.isEmpty()) {
2085-
status = U_MEMORY_ALLOCATION_ERROR;
2086-
setToBogus();
2087-
return;
2088-
}
2089-
heap = &payload.emplace<std::unique_ptr<Heap>>(std::move(copy));
2090-
if (!*heap) {
2091-
status = U_MEMORY_ALLOCATION_ERROR;
2092-
setToBogus();
2093-
return;
2094-
}
2095-
}
2096-
2097-
// The original computation of variantBegin leaves it equal to the length
2098-
// of fullName if there is no variant. It should instead be
2099-
// the length of the baseName.
2100-
if ((*heap)->variantBegin > baseNameLength) {
2101-
(*heap)->variantBegin = baseNameLength;
2102-
}
2103-
2104-
(*heap)->baseName = {fullName, static_cast<std::string_view::size_type>(baseNameLength)};
2105-
if ((*heap)->baseName.isEmpty()) {
2106-
status = U_MEMORY_ALLOCATION_ERROR;
2107-
setToBogus();
2108-
return;
2109-
}
2110-
}
2111-
}
2112-
2113-
21142052
int32_t
21152053
Locale::hashCode() const
21162054
{
@@ -2753,8 +2691,11 @@ Locale::setKeywordValue(StringPiece keywordName,
27532691
return;
27542692
}
27552693

2694+
const char* at = locale_getKeywordsStart(localeID.toStringPiece());
2695+
bool hasKeywords = at != nullptr && uprv_strchr(at + 1, '=') != nullptr;
2696+
27562697
Nest* nest = std::get_if<Nest>(&payload);
2757-
if (locale_getKeywordsStart(localeID.toStringPiece()) == nullptr) {
2698+
if (!hasKeywords) {
27582699
if (nest == nullptr) {
27592700
// There are no longer any keywords left, so it might now be
27602701
// possible to move the payload from Heap to Nest.
@@ -2814,7 +2755,14 @@ Locale::setKeywordValue(StringPiece keywordName,
28142755

28152756
if ((*heap)->baseName.isEmpty()) {
28162757
// Has added the first keyword, meaning that the fullName is no longer also the baseName.
2817-
initBaseName(status);
2758+
if (std::string_view::size_type baseNameLength = at - localeID.data(); baseNameLength > 0) {
2759+
(*heap)->baseName = {(*heap)->fullName.data(), baseNameLength};
2760+
if ((*heap)->baseName.isEmpty()) {
2761+
status = U_MEMORY_ALLOCATION_ERROR;
2762+
setToBogus();
2763+
return;
2764+
}
2765+
}
28182766
}
28192767
}
28202768
}

icu4c/source/common/unicode/locid.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,8 +1237,6 @@ class U_COMMON_API_CLASS Locale : public UObject {
12371237
const char* (Heap::*const HEAP)() const>
12381238
const char* getField() const;
12391239

1240-
void initBaseName(UErrorCode& status);
1241-
12421240
static const Locale &getLocale(int locid);
12431241

12441242
/**

0 commit comments

Comments
 (0)