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-22901 Update Locale::init() to use StringPiece #3395

Merged
merged 1 commit into from
Feb 14, 2025
Merged
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
43 changes: 31 additions & 12 deletions icu4c/source/common/locid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1828,8 +1828,13 @@ ulocimp_isCanonicalizedLocaleForTest(const char* localeName)

U_NAMESPACE_BEGIN

/*This function initializes a Locale from a C locale ID*/
Locale& Locale::init(const char* localeID, UBool canonicalize)
{
return localeID == nullptr ? *this = getDefault() : init(StringPiece{localeID}, canonicalize);
}

/*This function initializes a Locale from a C locale ID*/
Locale& Locale::init(StringPiece localeID, UBool canonicalize)
{
fIsBogus = false;
/* Free our current storage */
Expand All @@ -1854,19 +1859,28 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
int32_t length;
UErrorCode err;

if(localeID == nullptr) {
// not an error, just set the default locale
return *this = getDefault();
}

/* preset all fields to empty */
language[0] = script[0] = country[0] = 0;

const auto parse = [canonicalize](std::string_view localeID,
char* name,
int32_t nameCapacity,
UErrorCode& status) {
return ByteSinkUtil::viaByteSinkToTerminatedChars(
name, nameCapacity,
[&](ByteSink& sink, UErrorCode& status) {
if (canonicalize) {
ulocimp_canonicalize(localeID, sink, status);
} else {
ulocimp_getName(localeID, sink, status);
}
},
status);
};

// "canonicalize" the locale ID to ICU/Java format
err = U_ZERO_ERROR;
length = canonicalize ?
uloc_canonicalize(localeID, fullName, sizeof(fullNameBuffer), &err) :
uloc_getName(localeID, fullName, sizeof(fullNameBuffer), &err);
length = parse(localeID, fullName, sizeof fullNameBuffer, err);

if (err == U_BUFFER_OVERFLOW_ERROR || length >= static_cast<int32_t>(sizeof(fullNameBuffer))) {
U_ASSERT(baseName == nullptr);
Expand All @@ -1877,9 +1891,7 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
}
fullName = newFullName;
err = U_ZERO_ERROR;
length = canonicalize ?
uloc_canonicalize(localeID, fullName, length+1, &err) :
uloc_getName(localeID, fullName, length+1, &err);
length = parse(localeID, fullName, length + 1, err);
}
if(U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
/* should never occur */
Expand Down Expand Up @@ -2200,6 +2212,13 @@ Locale::createFromName (const char *name)
}
}

Locale U_EXPORT2
Locale::createFromName(StringPiece name) {
Locale loc("");
loc.init(name, false);
return loc;
}

Locale U_EXPORT2
Locale::createCanonical(const char* name) {
Locale loc("");
Expand Down
5 changes: 1 addition & 4 deletions icu4c/source/common/ulocale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "unicode/locid.h"

#include "bytesinkutil.h"
#include "charstr.h"
#include "cmemory.h"

U_NAMESPACE_USE
Expand All @@ -24,9 +23,7 @@ ulocale_openForLocaleID(const char* localeID, int32_t length, UErrorCode* err) {
if (length < 0) {
return EXTERNAL(icu::Locale::createFromName(localeID).clone());
}
CharString str(localeID, length, *err); // Make a NUL terminated copy.
if (U_FAILURE(*err)) { return nullptr; }
return EXTERNAL(icu::Locale::createFromName(str.data()).clone());
return EXTERNAL(icu::Locale::createFromName(StringPiece{localeID, length}).clone());
}

ULocale*
Expand Down
9 changes: 8 additions & 1 deletion icu4c/source/common/unicode/locid.h
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,11 @@ class U_COMMON_API Locale : public UObject {
*/
static Locale U_EXPORT2 createFromName(const char *name);

#ifndef U_HIDE_INTERNAL_API
/** @internal */
static Locale U_EXPORT2 createFromName(StringPiece name);
#endif /* U_HIDE_INTERNAL_API */

/**
* Creates a locale from the given string after canonicalizing
* the string according to CLDR by calling uloc_canonicalize().
Expand Down Expand Up @@ -1133,7 +1138,9 @@ class U_COMMON_API Locale : public UObject {
* @param cLocaleID The new locale name.
* @param canonicalize whether to call uloc_canonicalize on cLocaleID
*/
Locale& init(const char* cLocaleID, UBool canonicalize);
Locale& init(const char* localeID, UBool canonicalize);
/** @internal */
Locale& init(StringPiece localeID, UBool canonicalize);

/*
* Internal constructor to allow construction of a locale object with
Expand Down