Update ICU to 75.1
This commit is contained in:
parent
557f63d037
commit
e74fea2864
|
@ -285,7 +285,7 @@ License: HarfBuzz
|
||||||
|
|
||||||
Files: ./thirdparty/icu4c/
|
Files: ./thirdparty/icu4c/
|
||||||
Comment: International Components for Unicode
|
Comment: International Components for Unicode
|
||||||
Copyright: 1991-2021, Unicode
|
Copyright: 2016-2024, Unicode, Inc.
|
||||||
License: Unicode
|
License: Unicode
|
||||||
|
|
||||||
Files: ./thirdparty/jpeg-compressor/
|
Files: ./thirdparty/jpeg-compressor/
|
||||||
|
|
|
@ -468,7 +468,7 @@ if env["builtin_icu4c"]:
|
||||||
]
|
]
|
||||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||||
|
|
||||||
icu_data_name = "icudt74l.dat"
|
icu_data_name = "icudt75l.dat"
|
||||||
|
|
||||||
if env.editor_build:
|
if env.editor_build:
|
||||||
env_icu.Depends("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name)
|
env_icu.Depends("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name)
|
||||||
|
|
|
@ -703,7 +703,7 @@ thirdparty_icu_sources = [
|
||||||
]
|
]
|
||||||
thirdparty_icu_sources = [thirdparty_icu_dir + file for file in thirdparty_icu_sources]
|
thirdparty_icu_sources = [thirdparty_icu_dir + file for file in thirdparty_icu_sources]
|
||||||
|
|
||||||
icu_data_name = "icudt74l.dat"
|
icu_data_name = "icudt75l.dat"
|
||||||
|
|
||||||
if env["static_icu_data"]:
|
if env["static_icu_data"]:
|
||||||
env_icu.Depends("../../../thirdparty/icu4c/icudata.gen.h", "../../../thirdparty/icu4c/" + icu_data_name)
|
env_icu.Depends("../../../thirdparty/icu4c/icudata.gen.h", "../../../thirdparty/icu4c/" + icu_data_name)
|
||||||
|
|
|
@ -391,7 +391,7 @@ Files extracted from upstream source:
|
||||||
## icu4c
|
## icu4c
|
||||||
|
|
||||||
- Upstream: https://github.com/unicode-org/icu
|
- Upstream: https://github.com/unicode-org/icu
|
||||||
- Version: 74.2 (2d029329c82c7792b985024b2bdab5fc7278fbc8, 2023)
|
- Version: 75.1 (7750081bda4b3bc1768ae03849ec70f67ea10625, 2024)
|
||||||
- License: Unicode
|
- License: Unicode
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
@ -403,7 +403,7 @@ Files extracted from upstream source:
|
||||||
|
|
||||||
Files generated from upstream source:
|
Files generated from upstream source:
|
||||||
|
|
||||||
- The `icudt74l.dat` built with the provided `godot_data.json` config file (see
|
- The `icudt75l.dat` built with the provided `godot_data.json` config file (see
|
||||||
https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md
|
https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md
|
||||||
for instructions).
|
for instructions).
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ Files generated from upstream source:
|
||||||
3. Reconfigure ICU with custom data config:
|
3. Reconfigure ICU with custom data config:
|
||||||
`ICU_DATA_FILTER_FILE={GODOT_SOURCE}/thirdparty/icu4c/godot_data.json ./runConfigureICU {PLATFORM} --with-data-packaging=common`
|
`ICU_DATA_FILTER_FILE={GODOT_SOURCE}/thirdparty/icu4c/godot_data.json ./runConfigureICU {PLATFORM} --with-data-packaging=common`
|
||||||
4. Delete `data/out` folder and rebuild data: `cd data && rm -rf ./out && make`
|
4. Delete `data/out` folder and rebuild data: `cd data && rm -rf ./out && make`
|
||||||
5. Copy `source/data/out/icudt74l.dat` to the `{GODOT_SOURCE}/thirdparty/icu4c/icudt74l.dat`
|
5. Copy `source/data/out/icudt75l.dat` to the `{GODOT_SOURCE}/thirdparty/icu4c/icudt75l.dat`
|
||||||
|
|
||||||
|
|
||||||
## jpeg-compressor
|
## jpeg-compressor
|
||||||
|
|
|
@ -2,7 +2,7 @@ UNICODE LICENSE V3
|
||||||
|
|
||||||
COPYRIGHT AND PERMISSION NOTICE
|
COPYRIGHT AND PERMISSION NOTICE
|
||||||
|
|
||||||
Copyright © 2016-2023 Unicode, Inc.
|
Copyright © 2016-2024 Unicode, Inc.
|
||||||
|
|
||||||
NOTICE TO USER: Carefully read the following legal agreement. BY
|
NOTICE TO USER: Carefully read the following legal agreement. BY
|
||||||
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
||||||
|
@ -38,6 +38,8 @@ not be used in advertising or otherwise to promote the sale, use or other
|
||||||
dealings in these Data Files or Software without prior written
|
dealings in these Data Files or Software without prior written
|
||||||
authorization of the copyright holder.
|
authorization of the copyright holder.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: Unicode-3.0
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Third-Party Software Licenses
|
Third-Party Software Licenses
|
||||||
|
|
|
@ -114,13 +114,11 @@ UnhandledEngine::handleCharacter(UChar32 c) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ICULanguageBreakFactory::ICULanguageBreakFactory(UErrorCode &/*status*/) {
|
ICULanguageBreakFactory::ICULanguageBreakFactory(UErrorCode &/*status*/) {
|
||||||
fEngines = 0;
|
fEngines = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ICULanguageBreakFactory::~ICULanguageBreakFactory() {
|
ICULanguageBreakFactory::~ICULanguageBreakFactory() {
|
||||||
if (fEngines != 0) {
|
|
||||||
delete fEngines;
|
delete fEngines;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICULanguageBreakFactory::ensureEngines(UErrorCode& status) {
|
void ICULanguageBreakFactory::ensureEngines(UErrorCode& status) {
|
||||||
|
|
|
@ -438,17 +438,14 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
|
||||||
UTRACE_ENTRY(UTRACE_UBRK_CREATE_LINE);
|
UTRACE_ENTRY(UTRACE_UBRK_CREATE_LINE);
|
||||||
uprv_strcpy(lb_lw, "line");
|
uprv_strcpy(lb_lw, "line");
|
||||||
UErrorCode kvStatus = U_ZERO_ERROR;
|
UErrorCode kvStatus = U_ZERO_ERROR;
|
||||||
CharString value;
|
auto value = loc.getKeywordValue<CharString>("lb", kvStatus);
|
||||||
CharStringByteSink valueSink(&value);
|
|
||||||
loc.getKeywordValue("lb", valueSink, kvStatus);
|
|
||||||
if (U_SUCCESS(kvStatus) && (value == "strict" || value == "normal" || value == "loose")) {
|
if (U_SUCCESS(kvStatus) && (value == "strict" || value == "normal" || value == "loose")) {
|
||||||
uprv_strcat(lb_lw, "_");
|
uprv_strcat(lb_lw, "_");
|
||||||
uprv_strcat(lb_lw, value.data());
|
uprv_strcat(lb_lw, value.data());
|
||||||
}
|
}
|
||||||
// lw=phrase is only supported in Japanese and Korean
|
// lw=phrase is only supported in Japanese and Korean
|
||||||
if (uprv_strcmp(loc.getLanguage(), "ja") == 0 || uprv_strcmp(loc.getLanguage(), "ko") == 0) {
|
if (uprv_strcmp(loc.getLanguage(), "ja") == 0 || uprv_strcmp(loc.getLanguage(), "ko") == 0) {
|
||||||
value.clear();
|
value = loc.getKeywordValue<CharString>("lw", kvStatus);
|
||||||
loc.getKeywordValue("lw", valueSink, kvStatus);
|
|
||||||
if (U_SUCCESS(kvStatus) && value == "phrase") {
|
if (U_SUCCESS(kvStatus) && value == "phrase") {
|
||||||
uprv_strcat(lb_lw, "_");
|
uprv_strcat(lb_lw, "_");
|
||||||
uprv_strcat(lb_lw, value.data());
|
uprv_strcat(lb_lw, value.data());
|
||||||
|
@ -500,7 +497,7 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
|
||||||
Locale
|
Locale
|
||||||
BreakIterator::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
|
BreakIterator::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
|
||||||
if (type == ULOC_REQUESTED_LOCALE) {
|
if (type == ULOC_REQUESTED_LOCALE) {
|
||||||
return Locale(requestLocale);
|
return {requestLocale};
|
||||||
}
|
}
|
||||||
U_LOCALE_BASED(locBased, *this);
|
U_LOCALE_BASED(locBased, *this);
|
||||||
return locBased.getLocale(type, status);
|
return locBased.getLocale(type, status);
|
||||||
|
|
|
@ -7,18 +7,52 @@
|
||||||
#ifndef BYTESINKUTIL_H
|
#ifndef BYTESINKUTIL_H
|
||||||
#define BYTESINKUTIL_H
|
#define BYTESINKUTIL_H
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "unicode/utypes.h"
|
#include "unicode/utypes.h"
|
||||||
#include "unicode/bytestream.h"
|
#include "unicode/bytestream.h"
|
||||||
#include "unicode/edits.h"
|
#include "unicode/edits.h"
|
||||||
|
#include "charstr.h"
|
||||||
#include "cmemory.h"
|
#include "cmemory.h"
|
||||||
#include "uassert.h"
|
#include "uassert.h"
|
||||||
|
#include "ustr_imp.h"
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
class ByteSink;
|
class ByteSink;
|
||||||
class CharString;
|
|
||||||
class Edits;
|
class Edits;
|
||||||
|
|
||||||
|
class U_COMMON_API CharStringByteSink : public ByteSink {
|
||||||
|
public:
|
||||||
|
CharStringByteSink(CharString* dest);
|
||||||
|
~CharStringByteSink() override;
|
||||||
|
|
||||||
|
CharStringByteSink() = delete;
|
||||||
|
CharStringByteSink(const CharStringByteSink&) = delete;
|
||||||
|
CharStringByteSink& operator=(const CharStringByteSink&) = delete;
|
||||||
|
|
||||||
|
void Append(const char* bytes, int32_t n) override;
|
||||||
|
|
||||||
|
char* GetAppendBuffer(int32_t min_capacity,
|
||||||
|
int32_t desired_capacity_hint,
|
||||||
|
char* scratch,
|
||||||
|
int32_t scratch_capacity,
|
||||||
|
int32_t* result_capacity) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CharString& dest_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CharString doesn't provide the public API that StringByteSink requires a
|
||||||
|
// string class to have so this template specialization replaces the default
|
||||||
|
// implementation of StringByteSink<CharString> with CharStringByteSink.
|
||||||
|
template<>
|
||||||
|
class StringByteSink<CharString> : public CharStringByteSink {
|
||||||
|
public:
|
||||||
|
StringByteSink(CharString* dest) : CharStringByteSink(dest) { }
|
||||||
|
StringByteSink(CharString* dest, int32_t /*initialAppendCapacity*/) : CharStringByteSink(dest) { }
|
||||||
|
};
|
||||||
|
|
||||||
class U_COMMON_API ByteSinkUtil {
|
class U_COMMON_API ByteSinkUtil {
|
||||||
public:
|
public:
|
||||||
ByteSinkUtil() = delete; // all static
|
ByteSinkUtil() = delete; // all static
|
||||||
|
@ -57,32 +91,66 @@ public:
|
||||||
ByteSink &sink, uint32_t options, Edits *edits,
|
ByteSink &sink, uint32_t options, Edits *edits,
|
||||||
UErrorCode &errorCode);
|
UErrorCode &errorCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a lambda that writes to a ByteSink with a CheckedArrayByteSink
|
||||||
|
* and then returns through u_terminateChars(), in order to implement
|
||||||
|
* the classic ICU4C C API writing to a fix sized buffer on top of a
|
||||||
|
* contemporary C++ API.
|
||||||
|
*
|
||||||
|
* @param buffer receiving buffer
|
||||||
|
* @param capacity capacity of receiving buffer
|
||||||
|
* @param lambda that gets called with the sink as an argument
|
||||||
|
* @param status set to U_BUFFER_OVERFLOW_ERROR on overflow
|
||||||
|
* @return number of bytes written, or needed (in case of overflow)
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
template <typename F,
|
||||||
|
typename = std::enable_if_t<
|
||||||
|
std::is_invocable_r_v<void, F, ByteSink&, UErrorCode&>>>
|
||||||
|
static int32_t viaByteSinkToTerminatedChars(char* buffer, int32_t capacity,
|
||||||
|
F&& lambda,
|
||||||
|
UErrorCode& status) {
|
||||||
|
if (U_FAILURE(status)) { return 0; }
|
||||||
|
CheckedArrayByteSink sink(buffer, capacity);
|
||||||
|
lambda(sink, status);
|
||||||
|
if (U_FAILURE(status)) { return 0; }
|
||||||
|
|
||||||
|
int32_t reslen = sink.NumberOfBytesAppended();
|
||||||
|
|
||||||
|
if (sink.Overflowed()) {
|
||||||
|
status = U_BUFFER_OVERFLOW_ERROR;
|
||||||
|
return reslen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return u_terminateChars(buffer, capacity, reslen, &status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a lambda that writes to a ByteSink with a CharStringByteSink and
|
||||||
|
* then returns a CharString, in order to implement a contemporary C++ API
|
||||||
|
* on top of a C/C++ compatibility ByteSink API.
|
||||||
|
*
|
||||||
|
* @param lambda that gets called with the sink as an argument
|
||||||
|
* @param status to check and report
|
||||||
|
* @return the resulting string, or an empty string (in case of error)
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
template <typename F,
|
||||||
|
typename = std::enable_if_t<
|
||||||
|
std::is_invocable_r_v<void, F, ByteSink&, UErrorCode&>>>
|
||||||
|
static CharString viaByteSinkToCharString(F&& lambda, UErrorCode& status) {
|
||||||
|
if (U_FAILURE(status)) { return {}; }
|
||||||
|
CharString result;
|
||||||
|
CharStringByteSink sink(&result);
|
||||||
|
lambda(sink, status);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void appendNonEmptyUnchanged(const uint8_t *s, int32_t length,
|
static void appendNonEmptyUnchanged(const uint8_t *s, int32_t length,
|
||||||
ByteSink &sink, uint32_t options, Edits *edits);
|
ByteSink &sink, uint32_t options, Edits *edits);
|
||||||
};
|
};
|
||||||
|
|
||||||
class U_COMMON_API CharStringByteSink : public ByteSink {
|
|
||||||
public:
|
|
||||||
CharStringByteSink(CharString* dest);
|
|
||||||
~CharStringByteSink() override;
|
|
||||||
|
|
||||||
CharStringByteSink() = delete;
|
|
||||||
CharStringByteSink(const CharStringByteSink&) = delete;
|
|
||||||
CharStringByteSink& operator=(const CharStringByteSink&) = delete;
|
|
||||||
|
|
||||||
void Append(const char* bytes, int32_t n) override;
|
|
||||||
|
|
||||||
char* GetAppendBuffer(int32_t min_capacity,
|
|
||||||
int32_t desired_capacity_hint,
|
|
||||||
char* scratch,
|
|
||||||
int32_t scratch_capacity,
|
|
||||||
int32_t* result_capacity) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CharString& dest_;
|
|
||||||
};
|
|
||||||
|
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
|
||||||
#endif //BYTESINKUTIL_H
|
#endif //BYTESINKUTIL_H
|
||||||
|
|
|
@ -64,6 +64,7 @@ U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CanonicalIterator)
|
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CanonicalIterator)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@param source string to get results for
|
*@param source string to get results for
|
||||||
*/
|
*/
|
||||||
|
@ -73,10 +74,10 @@ CanonicalIterator::CanonicalIterator(const UnicodeString &sourceStr, UErrorCode
|
||||||
pieces_lengths(nullptr),
|
pieces_lengths(nullptr),
|
||||||
current(nullptr),
|
current(nullptr),
|
||||||
current_length(0),
|
current_length(0),
|
||||||
nfd(*Normalizer2::getNFDInstance(status)),
|
nfd(Normalizer2::getNFDInstance(status)),
|
||||||
nfcImpl(*Normalizer2Factory::getNFCImpl(status))
|
nfcImpl(Normalizer2Factory::getNFCImpl(status))
|
||||||
{
|
{
|
||||||
if(U_SUCCESS(status) && nfcImpl.ensureCanonIterData(status)) {
|
if(U_SUCCESS(status) && nfcImpl->ensureCanonIterData(status)) {
|
||||||
setSource(sourceStr, status);
|
setSource(sourceStr, status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +173,7 @@ void CanonicalIterator::setSource(const UnicodeString &newSource, UErrorCode &st
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
UnicodeString *list = nullptr;
|
UnicodeString *list = nullptr;
|
||||||
|
|
||||||
nfd.normalize(newSource, source, status);
|
nfd->normalize(newSource, source, status);
|
||||||
if(U_FAILURE(status)) {
|
if(U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +195,7 @@ void CanonicalIterator::setSource(const UnicodeString &newSource, UErrorCode &st
|
||||||
current[0] = 0;
|
current[0] = 0;
|
||||||
pieces[0] = new UnicodeString[1];
|
pieces[0] = new UnicodeString[1];
|
||||||
pieces_lengths[0] = 1;
|
pieces_lengths[0] = 1;
|
||||||
if (pieces[0] == 0) {
|
if (pieces[0] == nullptr) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
goto CleanPartialInitialization;
|
goto CleanPartialInitialization;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +204,7 @@ void CanonicalIterator::setSource(const UnicodeString &newSource, UErrorCode &st
|
||||||
|
|
||||||
|
|
||||||
list = new UnicodeString[source.length()];
|
list = new UnicodeString[source.length()];
|
||||||
if (list == 0) {
|
if (list == nullptr) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
goto CleanPartialInitialization;
|
goto CleanPartialInitialization;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +220,7 @@ void CanonicalIterator::setSource(const UnicodeString &newSource, UErrorCode &st
|
||||||
// on the NFD form - see above).
|
// on the NFD form - see above).
|
||||||
for (; i < source.length(); i += U16_LENGTH(cp)) {
|
for (; i < source.length(); i += U16_LENGTH(cp)) {
|
||||||
cp = source.char32At(i);
|
cp = source.char32At(i);
|
||||||
if (nfcImpl.isCanonSegmentStarter(cp)) {
|
if (nfcImpl->isCanonSegmentStarter(cp)) {
|
||||||
source.extract(start, i-start, list[list_length++]); // add up to i
|
source.extract(start, i-start, list[list_length++]); // add up to i
|
||||||
start = i;
|
start = i;
|
||||||
}
|
}
|
||||||
|
@ -252,9 +253,7 @@ void CanonicalIterator::setSource(const UnicodeString &newSource, UErrorCode &st
|
||||||
return;
|
return;
|
||||||
// Common section to cleanup all local variables and reset object variables.
|
// Common section to cleanup all local variables and reset object variables.
|
||||||
CleanPartialInitialization:
|
CleanPartialInitialization:
|
||||||
if (list != nullptr) {
|
|
||||||
delete[] list;
|
delete[] list;
|
||||||
}
|
|
||||||
cleanPieces();
|
cleanPieces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,10 +263,19 @@ CleanPartialInitialization:
|
||||||
* @param source the string to find permutations for
|
* @param source the string to find permutations for
|
||||||
* @return the results in a set.
|
* @return the results in a set.
|
||||||
*/
|
*/
|
||||||
void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status) {
|
void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status, int32_t depth) {
|
||||||
if(U_FAILURE(status)) {
|
if(U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// To avoid infinity loop caused by permute, we limit the depth of recursive
|
||||||
|
// call to permute and return U_UNSUPPORTED_ERROR.
|
||||||
|
// We know in some unit test we need at least 4. Set to 8 just in case some
|
||||||
|
// unforseen use cases.
|
||||||
|
constexpr int32_t kPermuteDepthLimit = 8;
|
||||||
|
if (depth > kPermuteDepthLimit) {
|
||||||
|
status = U_UNSUPPORTED_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
//if (PROGRESS) printf("Permute: %s\n", UToS(Tr(source)));
|
//if (PROGRESS) printf("Permute: %s\n", UToS(Tr(source)));
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
|
|
||||||
|
@ -277,7 +285,7 @@ void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros
|
||||||
if (source.length() <= 2 && source.countChar32() <= 1) {
|
if (source.length() <= 2 && source.countChar32() <= 1) {
|
||||||
UnicodeString *toPut = new UnicodeString(source);
|
UnicodeString *toPut = new UnicodeString(source);
|
||||||
/* test for nullptr */
|
/* test for nullptr */
|
||||||
if (toPut == 0) {
|
if (toPut == nullptr) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +319,7 @@ void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros
|
||||||
|
|
||||||
// see what the permutations of the characters before and after this one are
|
// see what the permutations of the characters before and after this one are
|
||||||
//Hashtable *subpermute = permute(source.substring(0,i) + source.substring(i + UTF16.getCharCount(cp)));
|
//Hashtable *subpermute = permute(source.substring(0,i) + source.substring(i + UTF16.getCharCount(cp)));
|
||||||
permute(subPermuteString.remove(i, U16_LENGTH(cp)), skipZeros, &subpermute, status);
|
permute(subPermuteString.remove(i, U16_LENGTH(cp)), skipZeros, &subpermute, status, depth+1);
|
||||||
/* Test for buffer overflows */
|
/* Test for buffer overflows */
|
||||||
if(U_FAILURE(status)) {
|
if(U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
|
@ -346,7 +354,7 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
|
||||||
Hashtable permutations(status);
|
Hashtable permutations(status);
|
||||||
Hashtable basic(status);
|
Hashtable basic(status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
result.setValueDeleter(uprv_deleteUObject);
|
result.setValueDeleter(uprv_deleteUObject);
|
||||||
permutations.setValueDeleter(uprv_deleteUObject);
|
permutations.setValueDeleter(uprv_deleteUObject);
|
||||||
|
@ -381,7 +389,7 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
|
||||||
//UnicodeString *possible = new UnicodeString(*((UnicodeString *)(ne2->value.pointer)));
|
//UnicodeString *possible = new UnicodeString(*((UnicodeString *)(ne2->value.pointer)));
|
||||||
UnicodeString possible(*((UnicodeString *)(ne2->value.pointer)));
|
UnicodeString possible(*((UnicodeString *)(ne2->value.pointer)));
|
||||||
UnicodeString attempt;
|
UnicodeString attempt;
|
||||||
nfd.normalize(possible, attempt, status);
|
nfd->normalize(possible, attempt, status);
|
||||||
|
|
||||||
// TODO: check if operator == is semanticaly the same as attempt.equals(segment)
|
// TODO: check if operator == is semanticaly the same as attempt.equals(segment)
|
||||||
if (attempt==segment) {
|
if (attempt==segment) {
|
||||||
|
@ -399,7 +407,7 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
|
||||||
|
|
||||||
/* Test for buffer overflows */
|
/* Test for buffer overflows */
|
||||||
if(U_FAILURE(status)) {
|
if(U_FAILURE(status)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// convert into a String[] to clean up storage
|
// convert into a String[] to clean up storage
|
||||||
//String[] finalResult = new String[result.size()];
|
//String[] finalResult = new String[result.size()];
|
||||||
|
@ -407,7 +415,7 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
|
||||||
int32_t resultCount;
|
int32_t resultCount;
|
||||||
if((resultCount = result.count()) != 0) {
|
if((resultCount = result.count()) != 0) {
|
||||||
finalResult = new UnicodeString[resultCount];
|
finalResult = new UnicodeString[resultCount];
|
||||||
if (finalResult == 0) {
|
if (finalResult == nullptr) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +456,7 @@ Hashtable *CanonicalIterator::getEquivalents2(Hashtable *fillinResult, const cha
|
||||||
for (int32_t i = 0; i < segLen; i += U16_LENGTH(cp)) {
|
for (int32_t i = 0; i < segLen; i += U16_LENGTH(cp)) {
|
||||||
// see if any character is at the start of some decomposition
|
// see if any character is at the start of some decomposition
|
||||||
U16_GET(segment, 0, i, segLen, cp);
|
U16_GET(segment, 0, i, segLen, cp);
|
||||||
if (!nfcImpl.getCanonStartSet(cp, starts)) {
|
if (!nfcImpl->getCanonStartSet(cp, starts)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// if so, see which decompositions match
|
// if so, see which decompositions match
|
||||||
|
@ -471,7 +479,7 @@ Hashtable *CanonicalIterator::getEquivalents2(Hashtable *fillinResult, const cha
|
||||||
UnicodeString item = *((UnicodeString *)(ne->value.pointer));
|
UnicodeString item = *((UnicodeString *)(ne->value.pointer));
|
||||||
UnicodeString *toAdd = new UnicodeString(prefix);
|
UnicodeString *toAdd = new UnicodeString(prefix);
|
||||||
/* test for nullptr */
|
/* test for nullptr */
|
||||||
if (toAdd == 0) {
|
if (toAdd == nullptr) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -509,7 +517,7 @@ Hashtable *CanonicalIterator::extract(Hashtable *fillinResult, UChar32 comp, con
|
||||||
UnicodeString temp(comp);
|
UnicodeString temp(comp);
|
||||||
int32_t inputLen=temp.length();
|
int32_t inputLen=temp.length();
|
||||||
UnicodeString decompString;
|
UnicodeString decompString;
|
||||||
nfd.normalize(temp, decompString, status);
|
nfd->normalize(temp, decompString, status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +581,7 @@ Hashtable *CanonicalIterator::extract(Hashtable *fillinResult, UChar32 comp, con
|
||||||
// brute force approach
|
// brute force approach
|
||||||
// check to make sure result is canonically equivalent
|
// check to make sure result is canonically equivalent
|
||||||
UnicodeString trial;
|
UnicodeString trial;
|
||||||
nfd.normalize(temp, trial, status);
|
nfd->normalize(temp, trial, status);
|
||||||
if(U_FAILURE(status) || trial.compare(segment+segmentPos, segLen - segmentPos) != 0) {
|
if(U_FAILURE(status) || trial.compare(segment+segmentPos, segLen - segmentPos) != 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,13 @@ public:
|
||||||
*/
|
*/
|
||||||
int32_t extract(char *dest, int32_t capacity, UErrorCode &errorCode) const;
|
int32_t extract(char *dest, int32_t capacity, UErrorCode &errorCode) const;
|
||||||
|
|
||||||
|
bool operator==(const CharString& other) const {
|
||||||
|
return len == other.length() && (len == 0 || uprv_memcmp(data(), other.data(), len) == 0);
|
||||||
|
}
|
||||||
|
bool operator!=(const CharString& other) const {
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(StringPiece other) const {
|
bool operator==(StringPiece other) const {
|
||||||
return len == other.length() && (len == 0 || uprv_memcmp(data(), other.data(), len) == 0);
|
return len == other.length() && (len == 0 || uprv_memcmp(data(), other.data(), len) == 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ public:
|
||||||
if(umtx_atomic_dec(&refcount) <= 0) {
|
if(umtx_atomic_dec(&refcount) <= 0) {
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual ~SimpleFilteredSentenceBreakData();
|
virtual ~SimpleFilteredSentenceBreakData();
|
||||||
|
|
||||||
|
|
|
@ -148,12 +148,12 @@ inline void Hashtable::initSize(UHashFunction *keyHash, UKeyComparator *keyComp,
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp,
|
inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp,
|
||||||
UErrorCode& status) : hash(0) {
|
UErrorCode& status) : hash(nullptr) {
|
||||||
init( uhash_hashUnicodeString, keyComp, valueComp, status);
|
init( uhash_hashUnicodeString, keyComp, valueComp, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
|
inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
|
||||||
: hash(0)
|
: hash(nullptr)
|
||||||
{
|
{
|
||||||
init(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
init(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
||||||
: uhash_hashUnicodeString,
|
: uhash_hashUnicodeString,
|
||||||
|
@ -164,7 +164,7 @@ inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Hashtable::Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status)
|
inline Hashtable::Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status)
|
||||||
: hash(0)
|
: hash(nullptr)
|
||||||
{
|
{
|
||||||
initSize(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
initSize(ignoreKeyCase ? uhash_hashCaselessUnicodeString
|
||||||
: uhash_hashUnicodeString,
|
: uhash_hashUnicodeString,
|
||||||
|
@ -175,13 +175,13 @@ inline Hashtable::Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& statu
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Hashtable::Hashtable(UErrorCode& status)
|
inline Hashtable::Hashtable(UErrorCode& status)
|
||||||
: hash(0)
|
: hash(nullptr)
|
||||||
{
|
{
|
||||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, nullptr, status);
|
init(uhash_hashUnicodeString, uhash_compareUnicodeString, nullptr, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Hashtable::Hashtable()
|
inline Hashtable::Hashtable()
|
||||||
: hash(0)
|
: hash(nullptr)
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
init(uhash_hashUnicodeString, uhash_compareUnicodeString, nullptr, status);
|
init(uhash_hashUnicodeString, uhash_compareUnicodeString, nullptr, status);
|
||||||
|
|
|
@ -3,21 +3,21 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "bytesinkutil.h" // CharStringByteSink
|
#include "bytesinkutil.h" // StringByteSink<CharString>
|
||||||
#include "charstr.h"
|
#include "charstr.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
#include "ulocimp.h"
|
#include "ulocimp.h"
|
||||||
#include "unicode/localebuilder.h"
|
#include "unicode/localebuilder.h"
|
||||||
#include "unicode/locid.h"
|
#include "unicode/locid.h"
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
namespace {
|
||||||
|
|
||||||
#define UPRV_ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
|
inline bool UPRV_ISDIGIT(char c) { return c >= '0' && c <= '9'; }
|
||||||
#define UPRV_ISALPHANUM(c) (uprv_isASCIILetter(c) || UPRV_ISDIGIT(c) )
|
inline bool UPRV_ISALPHANUM(char c) { return uprv_isASCIILetter(c) || UPRV_ISDIGIT(c); }
|
||||||
|
|
||||||
constexpr const char* kAttributeKey = "attribute";
|
constexpr const char* kAttributeKey = "attribute";
|
||||||
|
|
||||||
static bool _isExtensionSubtags(char key, const char* s, int32_t len) {
|
bool _isExtensionSubtags(char key, const char* s, int32_t len) {
|
||||||
switch (uprv_tolower(key)) {
|
switch (uprv_tolower(key)) {
|
||||||
case 'u':
|
case 'u':
|
||||||
return ultag_isUnicodeExtensionSubtags(s, len);
|
return ultag_isUnicodeExtensionSubtags(s, len);
|
||||||
|
@ -30,6 +30,10 @@ static bool _isExtensionSubtags(char key, const char* s, int32_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
LocaleBuilder::LocaleBuilder() : UObject(), status_(U_ZERO_ERROR), language_(),
|
LocaleBuilder::LocaleBuilder() : UObject(), status_(U_ZERO_ERROR), language_(),
|
||||||
script_(), region_(), variant_(nullptr), extensions_(nullptr)
|
script_(), region_(), variant_(nullptr), extensions_(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -68,8 +72,10 @@ LocaleBuilder& LocaleBuilder::setLanguageTag(StringPiece tag)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setField(StringPiece input, char* dest, UErrorCode& errorCode,
|
namespace {
|
||||||
UBool (*test)(const char*, int32_t)) {
|
|
||||||
|
void setField(StringPiece input, char* dest, UErrorCode& errorCode,
|
||||||
|
bool (*test)(const char*, int32_t)) {
|
||||||
if (U_FAILURE(errorCode)) { return; }
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
if (input.empty()) {
|
if (input.empty()) {
|
||||||
dest[0] = '\0';
|
dest[0] = '\0';
|
||||||
|
@ -81,6 +87,8 @@ static void setField(StringPiece input, char* dest, UErrorCode& errorCode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
LocaleBuilder& LocaleBuilder::setLanguage(StringPiece language)
|
LocaleBuilder& LocaleBuilder::setLanguage(StringPiece language)
|
||||||
{
|
{
|
||||||
setField(language, language_, status_, &ultag_isLanguageSubtag);
|
setField(language, language_, status_, &ultag_isLanguageSubtag);
|
||||||
|
@ -99,7 +107,9 @@ LocaleBuilder& LocaleBuilder::setRegion(StringPiece region)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transform(char* data, int32_t len) {
|
namespace {
|
||||||
|
|
||||||
|
void transform(char* data, int32_t len) {
|
||||||
for (int32_t i = 0; i < len; i++, data++) {
|
for (int32_t i = 0; i < len; i++, data++) {
|
||||||
if (*data == '_') {
|
if (*data == '_') {
|
||||||
*data = '-';
|
*data = '-';
|
||||||
|
@ -109,6 +119,8 @@ static void transform(char* data, int32_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
LocaleBuilder& LocaleBuilder::setVariant(StringPiece variant)
|
LocaleBuilder& LocaleBuilder::setVariant(StringPiece variant)
|
||||||
{
|
{
|
||||||
if (U_FAILURE(status_)) { return *this; }
|
if (U_FAILURE(status_)) { return *this; }
|
||||||
|
@ -134,7 +146,9 @@ LocaleBuilder& LocaleBuilder::setVariant(StringPiece variant)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
namespace {
|
||||||
|
|
||||||
|
bool
|
||||||
_isKeywordValue(const char* key, const char* value, int32_t value_len)
|
_isKeywordValue(const char* key, const char* value, int32_t value_len)
|
||||||
{
|
{
|
||||||
if (key[1] == '\0') {
|
if (key[1] == '\0') {
|
||||||
|
@ -156,7 +170,7 @@ _isKeywordValue(const char* key, const char* value, int32_t value_len)
|
||||||
ultag_isUnicodeLocaleType(unicode_locale_type, -1);
|
ultag_isUnicodeLocaleType(unicode_locale_type, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
_copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
|
_copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
|
||||||
Locale& to, bool validate, UErrorCode& errorCode)
|
Locale& to, bool validate, UErrorCode& errorCode)
|
||||||
{
|
{
|
||||||
|
@ -169,9 +183,7 @@ _copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
|
||||||
}
|
}
|
||||||
const char* key;
|
const char* key;
|
||||||
while ((key = keywords->next(nullptr, errorCode)) != nullptr) {
|
while ((key = keywords->next(nullptr, errorCode)) != nullptr) {
|
||||||
CharString value;
|
auto value = from.getKeywordValue<CharString>(key, errorCode);
|
||||||
CharStringByteSink sink(&value);
|
|
||||||
from.getKeywordValue(key, sink, errorCode);
|
|
||||||
if (U_FAILURE(errorCode)) { return; }
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
if (uprv_strcmp(key, kAttributeKey) == 0) {
|
if (uprv_strcmp(key, kAttributeKey) == 0) {
|
||||||
transform(value.data(), value.length());
|
transform(value.data(), value.length());
|
||||||
|
@ -186,9 +198,10 @@ _copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void static
|
void
|
||||||
_clearUAttributesAndKeyType(Locale& locale, UErrorCode& errorCode)
|
_clearUAttributesAndKeyType(Locale& locale, UErrorCode& errorCode)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
// Clear Unicode attributes
|
// Clear Unicode attributes
|
||||||
locale.setKeywordValue(kAttributeKey, "", errorCode);
|
locale.setKeywordValue(kAttributeKey, "", errorCode);
|
||||||
|
|
||||||
|
@ -201,9 +214,10 @@ _clearUAttributesAndKeyType(Locale& locale, UErrorCode& errorCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
_setUnicodeExtensions(Locale& locale, const CharString& value, UErrorCode& errorCode)
|
_setUnicodeExtensions(Locale& locale, const CharString& value, UErrorCode& errorCode)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
// Add the unicode extensions to extensions_
|
// Add the unicode extensions to extensions_
|
||||||
CharString locale_str("und-u-", errorCode);
|
CharString locale_str("und-u-", errorCode);
|
||||||
locale_str.append(value, errorCode);
|
locale_str.append(value, errorCode);
|
||||||
|
@ -212,6 +226,8 @@ _setUnicodeExtensions(Locale& locale, const CharString& value, UErrorCode& error
|
||||||
locale, false, errorCode);
|
locale, false, errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
LocaleBuilder& LocaleBuilder::setExtension(char key, StringPiece value)
|
LocaleBuilder& LocaleBuilder::setExtension(char key, StringPiece value)
|
||||||
{
|
{
|
||||||
if (U_FAILURE(status_)) { return *this; }
|
if (U_FAILURE(status_)) { return *this; }
|
||||||
|
@ -289,10 +305,8 @@ LocaleBuilder& LocaleBuilder::addUnicodeLocaleAttribute(
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString attributes;
|
|
||||||
CharStringByteSink sink(&attributes);
|
|
||||||
UErrorCode localErrorCode = U_ZERO_ERROR;
|
UErrorCode localErrorCode = U_ZERO_ERROR;
|
||||||
extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode);
|
auto attributes = extensions_->getKeywordValue<CharString>(kAttributeKey, localErrorCode);
|
||||||
if (U_FAILURE(localErrorCode)) {
|
if (U_FAILURE(localErrorCode)) {
|
||||||
CharString new_attributes(value_str.data(), status_);
|
CharString new_attributes(value_str.data(), status_);
|
||||||
// No attributes, set the attribute.
|
// No attributes, set the attribute.
|
||||||
|
@ -344,9 +358,7 @@ LocaleBuilder& LocaleBuilder::removeUnicodeLocaleAttribute(
|
||||||
}
|
}
|
||||||
if (extensions_ == nullptr) { return *this; }
|
if (extensions_ == nullptr) { return *this; }
|
||||||
UErrorCode localErrorCode = U_ZERO_ERROR;
|
UErrorCode localErrorCode = U_ZERO_ERROR;
|
||||||
CharString attributes;
|
auto attributes = extensions_->getKeywordValue<CharString>(kAttributeKey, localErrorCode);
|
||||||
CharStringByteSink sink(&attributes);
|
|
||||||
extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode);
|
|
||||||
// get failure, just return
|
// get failure, just return
|
||||||
if (U_FAILURE(localErrorCode)) { return *this; }
|
if (U_FAILURE(localErrorCode)) { return *this; }
|
||||||
// Do not have any attributes, just return.
|
// Do not have any attributes, just return.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,8 @@
|
||||||
// localematcher.cpp
|
// localematcher.cpp
|
||||||
// created: 2019may08 Markus W. Scherer
|
// created: 2019may08 Markus W. Scherer
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "unicode/utypes.h"
|
#include "unicode/utypes.h"
|
||||||
#include "unicode/localebuilder.h"
|
#include "unicode/localebuilder.h"
|
||||||
#include "unicode/localematcher.h"
|
#include "unicode/localematcher.h"
|
||||||
|
@ -302,7 +304,7 @@ LocaleMatcher LocaleMatcher::Builder::build(UErrorCode &errorCode) const {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
LSR getMaximalLsrOrUnd(const XLikelySubtags &likelySubtags, const Locale &locale,
|
LSR getMaximalLsrOrUnd(const LikelySubtags &likelySubtags, const Locale &locale,
|
||||||
UErrorCode &errorCode) {
|
UErrorCode &errorCode) {
|
||||||
if (U_FAILURE(errorCode) || locale.isBogus() || *locale.getName() == 0 /* "und" */) {
|
if (U_FAILURE(errorCode) || locale.isBogus() || *locale.getName() == 0 /* "und" */) {
|
||||||
return UND_LSR;
|
return UND_LSR;
|
||||||
|
@ -338,7 +340,7 @@ int32_t LocaleMatcher::putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength
|
||||||
}
|
}
|
||||||
|
|
||||||
LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
|
LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
|
||||||
likelySubtags(*XLikelySubtags::getSingleton(errorCode)),
|
likelySubtags(*LikelySubtags::getSingleton(errorCode)),
|
||||||
localeDistance(*LocaleDistance::getSingleton(errorCode)),
|
localeDistance(*LocaleDistance::getSingleton(errorCode)),
|
||||||
thresholdDistance(builder.thresholdDistance_),
|
thresholdDistance(builder.thresholdDistance_),
|
||||||
demotionPerDesiredLocale(0),
|
demotionPerDesiredLocale(0),
|
||||||
|
@ -551,7 +553,7 @@ LocaleMatcher &LocaleMatcher::operator=(LocaleMatcher &&src) noexcept {
|
||||||
|
|
||||||
class LocaleLsrIterator {
|
class LocaleLsrIterator {
|
||||||
public:
|
public:
|
||||||
LocaleLsrIterator(const XLikelySubtags &likelySubtags, Locale::Iterator &locales,
|
LocaleLsrIterator(const LikelySubtags &likelySubtags, Locale::Iterator &locales,
|
||||||
ULocMatchLifetime lifetime) :
|
ULocMatchLifetime lifetime) :
|
||||||
likelySubtags(likelySubtags), locales(locales), lifetime(lifetime) {}
|
likelySubtags(likelySubtags), locales(locales), lifetime(lifetime) {}
|
||||||
|
|
||||||
|
@ -596,7 +598,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const XLikelySubtags &likelySubtags;
|
const LikelySubtags &likelySubtags;
|
||||||
Locale::Iterator &locales;
|
Locale::Iterator &locales;
|
||||||
ULocMatchLifetime lifetime;
|
ULocMatchLifetime lifetime;
|
||||||
const Locale *current = nullptr, *remembered = nullptr;
|
const Locale *current = nullptr, *remembered = nullptr;
|
||||||
|
@ -605,10 +607,11 @@ private:
|
||||||
|
|
||||||
const Locale *LocaleMatcher::getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const {
|
const Locale *LocaleMatcher::getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const {
|
||||||
if (U_FAILURE(errorCode)) { return nullptr; }
|
if (U_FAILURE(errorCode)) { return nullptr; }
|
||||||
int32_t suppIndex = getBestSuppIndex(
|
std::optional<int32_t> suppIndex = getBestSuppIndex(
|
||||||
getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
|
getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
|
||||||
nullptr, errorCode);
|
nullptr, errorCode);
|
||||||
return U_SUCCESS(errorCode) && suppIndex >= 0 ? supportedLocales[suppIndex] : defaultLocale;
|
return U_SUCCESS(errorCode) && suppIndex.has_value() ? supportedLocales[*suppIndex]
|
||||||
|
: defaultLocale;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Locale *LocaleMatcher::getBestMatch(Locale::Iterator &desiredLocales,
|
const Locale *LocaleMatcher::getBestMatch(Locale::Iterator &desiredLocales,
|
||||||
|
@ -618,12 +621,14 @@ const Locale *LocaleMatcher::getBestMatch(Locale::Iterator &desiredLocales,
|
||||||
return defaultLocale;
|
return defaultLocale;
|
||||||
}
|
}
|
||||||
LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
|
LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
|
||||||
int32_t suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
|
std::optional<int32_t> suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
|
||||||
return U_SUCCESS(errorCode) && suppIndex >= 0 ? supportedLocales[suppIndex] : defaultLocale;
|
return U_SUCCESS(errorCode) && suppIndex.has_value() ? supportedLocales[*suppIndex]
|
||||||
|
: defaultLocale;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Locale *LocaleMatcher::getBestMatchForListString(
|
const Locale *LocaleMatcher::getBestMatchForListString(
|
||||||
StringPiece desiredLocaleList, UErrorCode &errorCode) const {
|
StringPiece desiredLocaleList, UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return nullptr; }
|
||||||
LocalePriorityList list(desiredLocaleList, errorCode);
|
LocalePriorityList list(desiredLocaleList, errorCode);
|
||||||
LocalePriorityList::Iterator iter = list.iterator();
|
LocalePriorityList::Iterator iter = list.iterator();
|
||||||
return getBestMatch(iter, errorCode);
|
return getBestMatch(iter, errorCode);
|
||||||
|
@ -634,13 +639,13 @@ LocaleMatcher::Result LocaleMatcher::getBestMatchResult(
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) {
|
||||||
return Result(nullptr, defaultLocale, -1, -1, false);
|
return Result(nullptr, defaultLocale, -1, -1, false);
|
||||||
}
|
}
|
||||||
int32_t suppIndex = getBestSuppIndex(
|
std::optional<int32_t> suppIndex = getBestSuppIndex(
|
||||||
getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
|
getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
|
||||||
nullptr, errorCode);
|
nullptr, errorCode);
|
||||||
if (U_FAILURE(errorCode) || suppIndex < 0) {
|
if (U_FAILURE(errorCode) || !suppIndex.has_value()) {
|
||||||
return Result(nullptr, defaultLocale, -1, -1, false);
|
return Result(nullptr, defaultLocale, -1, -1, false);
|
||||||
} else {
|
} else {
|
||||||
return Result(&desiredLocale, supportedLocales[suppIndex], 0, suppIndex, false);
|
return Result(&desiredLocale, supportedLocales[*suppIndex], 0, *suppIndex, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,18 +655,19 @@ LocaleMatcher::Result LocaleMatcher::getBestMatchResult(
|
||||||
return Result(nullptr, defaultLocale, -1, -1, false);
|
return Result(nullptr, defaultLocale, -1, -1, false);
|
||||||
}
|
}
|
||||||
LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
|
LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
|
||||||
int32_t suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
|
std::optional<int32_t> suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
|
||||||
if (U_FAILURE(errorCode) || suppIndex < 0) {
|
if (U_FAILURE(errorCode) || !suppIndex.has_value()) {
|
||||||
return Result(nullptr, defaultLocale, -1, -1, false);
|
return Result(nullptr, defaultLocale, -1, -1, false);
|
||||||
} else {
|
} else {
|
||||||
return Result(lsrIter.orphanRemembered(), supportedLocales[suppIndex],
|
return Result(lsrIter.orphanRemembered(), supportedLocales[*suppIndex],
|
||||||
lsrIter.getBestDesiredIndex(), suppIndex, true);
|
lsrIter.getBestDesiredIndex(), *suppIndex, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter,
|
std::optional<int32_t> LocaleMatcher::getBestSuppIndex(LSR desiredLSR,
|
||||||
|
LocaleLsrIterator *remainingIter,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
if (U_FAILURE(errorCode)) { return -1; }
|
if (U_FAILURE(errorCode)) { return std::nullopt; }
|
||||||
int32_t desiredIndex = 0;
|
int32_t desiredIndex = 0;
|
||||||
int32_t bestSupportedLsrIndex = -1;
|
int32_t bestSupportedLsrIndex = -1;
|
||||||
for (int32_t bestShiftedDistance = LocaleDistance::shiftDistance(thresholdDistance);;) {
|
for (int32_t bestShiftedDistance = LocaleDistance::shiftDistance(thresholdDistance);;) {
|
||||||
|
@ -684,7 +690,7 @@ int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remai
|
||||||
bestShiftedDistance = LocaleDistance::getShiftedDistance(bestIndexAndDistance);
|
bestShiftedDistance = LocaleDistance::getShiftedDistance(bestIndexAndDistance);
|
||||||
if (remainingIter != nullptr) {
|
if (remainingIter != nullptr) {
|
||||||
remainingIter->rememberCurrent(desiredIndex, errorCode);
|
remainingIter->rememberCurrent(desiredIndex, errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return -1; }
|
if (U_FAILURE(errorCode)) { return std::nullopt; }
|
||||||
}
|
}
|
||||||
bestSupportedLsrIndex = LocaleDistance::getIndex(bestIndexAndDistance);
|
bestSupportedLsrIndex = LocaleDistance::getIndex(bestIndexAndDistance);
|
||||||
}
|
}
|
||||||
|
@ -695,20 +701,21 @@ int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remai
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
desiredLSR = remainingIter->next(errorCode);
|
desiredLSR = remainingIter->next(errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return -1; }
|
if (U_FAILURE(errorCode)) { return std::nullopt; }
|
||||||
++desiredIndex;
|
++desiredIndex;
|
||||||
}
|
}
|
||||||
if (bestSupportedLsrIndex < 0) {
|
if (bestSupportedLsrIndex < 0) {
|
||||||
// no good match
|
// no good match
|
||||||
return -1;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return supportedIndexes[bestSupportedLsrIndex];
|
return supportedIndexes[bestSupportedLsrIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool LocaleMatcher::isMatch(const Locale &desired, const Locale &supported,
|
UBool LocaleMatcher::isMatch(const Locale &desired, const Locale &supported,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
|
LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return 0; }
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
const LSR *pSuppLSR = &suppLSR;
|
const LSR *pSuppLSR = &suppLSR;
|
||||||
int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
|
int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
|
||||||
getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
|
getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
|
||||||
|
@ -718,9 +725,10 @@ UBool LocaleMatcher::isMatch(const Locale &desired, const Locale &supported,
|
||||||
}
|
}
|
||||||
|
|
||||||
double LocaleMatcher::internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const {
|
double LocaleMatcher::internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return 0.; }
|
||||||
// Returns the inverse of the distance: That is, 1-distance(desired, supported).
|
// Returns the inverse of the distance: That is, 1-distance(desired, supported).
|
||||||
LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
|
LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return 0; }
|
if (U_FAILURE(errorCode)) { return 0.; }
|
||||||
const LSR *pSuppLSR = &suppLSR;
|
const LSR *pSuppLSR = &suppLSR;
|
||||||
int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
|
int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
|
||||||
getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
|
getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
|
||||||
|
|
|
@ -21,13 +21,13 @@ U_NAMESPACE_BEGIN
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
int32_t hashLocale(const UHashTok token) {
|
int32_t hashLocale(const UHashTok token) {
|
||||||
auto *locale = static_cast<const Locale *>(token.pointer);
|
const auto* locale = static_cast<const Locale*>(token.pointer);
|
||||||
return locale->hashCode();
|
return locale->hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool compareLocales(const UHashTok t1, const UHashTok t2) {
|
UBool compareLocales(const UHashTok t1, const UHashTok t2) {
|
||||||
auto *l1 = static_cast<const Locale *>(t1.pointer);
|
const auto* l1 = static_cast<const Locale*>(t1.pointer);
|
||||||
auto *l2 = static_cast<const Locale *>(t2.pointer);
|
const auto* l2 = static_cast<const Locale*>(t2.pointer);
|
||||||
return *l1 == *l2;
|
return *l1 == *l2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,14 +39,10 @@ static icu::Locale* availableLocaleList = nullptr;
|
||||||
static int32_t availableLocaleListCount;
|
static int32_t availableLocaleListCount;
|
||||||
static icu::UInitOnce gInitOnceLocale {};
|
static icu::UInitOnce gInitOnceLocale {};
|
||||||
|
|
||||||
U_NAMESPACE_END
|
namespace {
|
||||||
|
|
||||||
U_CDECL_BEGIN
|
UBool U_CALLCONV locale_available_cleanup()
|
||||||
|
|
||||||
static UBool U_CALLCONV locale_available_cleanup()
|
|
||||||
{
|
{
|
||||||
U_NAMESPACE_USE
|
|
||||||
|
|
||||||
if (availableLocaleList) {
|
if (availableLocaleList) {
|
||||||
delete []availableLocaleList;
|
delete []availableLocaleList;
|
||||||
availableLocaleList = nullptr;
|
availableLocaleList = nullptr;
|
||||||
|
@ -57,9 +53,7 @@ static UBool U_CALLCONV locale_available_cleanup()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CDECL_END
|
} // namespace
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
void U_CALLCONV locale_available_init() {
|
void U_CALLCONV locale_available_init() {
|
||||||
// This function is a friend of class Locale.
|
// This function is a friend of class Locale.
|
||||||
|
@ -107,10 +101,9 @@ icu::UInitOnce ginstalledLocalesInitOnce {};
|
||||||
class AvailableLocalesSink : public ResourceSink {
|
class AvailableLocalesSink : public ResourceSink {
|
||||||
public:
|
public:
|
||||||
void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) override {
|
void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) override {
|
||||||
|
if (U_FAILURE(status)) { return; }
|
||||||
ResourceTable resIndexTable = value.getTable(status);
|
ResourceTable resIndexTable = value.getTable(status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int32_t i = 0; resIndexTable.getKeyAndValue(i, key, value); ++i) {
|
for (int32_t i = 0; resIndexTable.getKeyAndValue(i, key, value); ++i) {
|
||||||
ULocAvailableType type;
|
ULocAvailableType type;
|
||||||
if (uprv_strcmp(key, "InstalledLocales") == 0) {
|
if (uprv_strcmp(key, "InstalledLocales") == 0) {
|
||||||
|
@ -144,7 +137,8 @@ class AvailableLocalesStringEnumeration : public StringEnumeration {
|
||||||
AvailableLocalesStringEnumeration(ULocAvailableType type) : fType(type) {
|
AvailableLocalesStringEnumeration(ULocAvailableType type) : fType(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* next(int32_t *resultLength, UErrorCode&) override {
|
const char* next(int32_t *resultLength, UErrorCode &status) override {
|
||||||
|
if (U_FAILURE(status)) { return nullptr; }
|
||||||
ULocAvailableType actualType = fType;
|
ULocAvailableType actualType = fType;
|
||||||
int32_t actualIndex = fIndex++;
|
int32_t actualIndex = fIndex++;
|
||||||
|
|
||||||
|
@ -176,11 +170,13 @@ class AvailableLocalesStringEnumeration : public StringEnumeration {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(UErrorCode&) override {
|
void reset(UErrorCode &status) override {
|
||||||
|
if (U_FAILURE(status)) { return; }
|
||||||
fIndex = 0;
|
fIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t count(UErrorCode&) const override {
|
int32_t count(UErrorCode &status) const override {
|
||||||
|
if (U_FAILURE(status)) { return 0; }
|
||||||
if (fType == ULOC_AVAILABLE_WITH_LEGACY_ALIASES) {
|
if (fType == ULOC_AVAILABLE_WITH_LEGACY_ALIASES) {
|
||||||
return gAvailableLocaleCounts[ULOC_AVAILABLE_DEFAULT]
|
return gAvailableLocaleCounts[ULOC_AVAILABLE_DEFAULT]
|
||||||
+ gAvailableLocaleCounts[ULOC_AVAILABLE_ONLY_LEGACY_ALIASES];
|
+ gAvailableLocaleCounts[ULOC_AVAILABLE_ONLY_LEGACY_ALIASES];
|
||||||
|
@ -196,7 +192,7 @@ class AvailableLocalesStringEnumeration : public StringEnumeration {
|
||||||
|
|
||||||
/* ### Get available **************************************************/
|
/* ### Get available **************************************************/
|
||||||
|
|
||||||
static UBool U_CALLCONV uloc_cleanup() {
|
UBool U_CALLCONV uloc_cleanup() {
|
||||||
for (int32_t i = 0; i < UPRV_LENGTHOF(gAvailableLocaleNames); i++) {
|
for (int32_t i = 0; i < UPRV_LENGTHOF(gAvailableLocaleNames); i++) {
|
||||||
uprv_free(gAvailableLocaleNames[i]);
|
uprv_free(gAvailableLocaleNames[i]);
|
||||||
gAvailableLocaleNames[i] = nullptr;
|
gAvailableLocaleNames[i] = nullptr;
|
||||||
|
@ -209,7 +205,7 @@ static UBool U_CALLCONV uloc_cleanup() {
|
||||||
// Load Installed Locales. This function will be called exactly once
|
// Load Installed Locales. This function will be called exactly once
|
||||||
// via the initOnce mechanism.
|
// via the initOnce mechanism.
|
||||||
|
|
||||||
static void U_CALLCONV loadInstalledLocales(UErrorCode& status) {
|
void U_CALLCONV loadInstalledLocales(UErrorCode& status) {
|
||||||
ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
|
ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
|
||||||
|
|
||||||
icu::LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "res_index", &status));
|
icu::LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "res_index", &status));
|
||||||
|
@ -267,4 +263,3 @@ uloc_openAvailableByType(ULocAvailableType type, UErrorCode* status) {
|
||||||
}
|
}
|
||||||
return uenum_openFromStringEnumeration(result.orphan(), status);
|
return uenum_openFromStringEnumeration(result.orphan(), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
Locale LocaleBased::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
|
Locale LocaleBased::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
|
||||||
const char* id = getLocaleID(type, status);
|
const char* id = getLocaleID(type, status);
|
||||||
return Locale((id != 0) ? id : "");
|
return Locale(id != nullptr ? id : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* LocaleBased::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
|
const char* LocaleBased::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
|
||||||
|
@ -37,11 +37,11 @@ const char* LocaleBased::getLocaleID(ULocDataLocaleType type, UErrorCode& status
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocaleBased::setLocaleIDs(const char* validID, const char* actualID) {
|
void LocaleBased::setLocaleIDs(const char* validID, const char* actualID) {
|
||||||
if (validID != 0) {
|
if (validID != nullptr) {
|
||||||
uprv_strncpy(valid, validID, ULOC_FULLNAME_CAPACITY);
|
uprv_strncpy(valid, validID, ULOC_FULLNAME_CAPACITY);
|
||||||
valid[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
|
valid[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
|
||||||
}
|
}
|
||||||
if (actualID != 0) {
|
if (actualID != nullptr) {
|
||||||
uprv_strncpy(actual, actualID, ULOC_FULLNAME_CAPACITY);
|
uprv_strncpy(actual, actualID, ULOC_FULLNAME_CAPACITY);
|
||||||
actual[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
|
actual[ULOC_FULLNAME_CAPACITY-1] = 0; // always terminate
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "unicode/uloc.h"
|
#include "unicode/uloc.h"
|
||||||
#include "unicode/ures.h"
|
#include "unicode/ures.h"
|
||||||
#include "unicode/ustring.h"
|
#include "unicode/ustring.h"
|
||||||
#include "bytesinkutil.h"
|
|
||||||
#include "charstr.h"
|
#include "charstr.h"
|
||||||
#include "cmemory.h"
|
#include "cmemory.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
|
@ -60,7 +59,7 @@ Locale::getDisplayLanguage(const Locale &displayLocale,
|
||||||
int32_t length;
|
int32_t length;
|
||||||
|
|
||||||
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,7 @@ Locale::getDisplayLanguage(const Locale &displayLocale,
|
||||||
|
|
||||||
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
||||||
buffer=result.getBuffer(length);
|
buffer=result.getBuffer(length);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +99,7 @@ Locale::getDisplayScript(const Locale &displayLocale,
|
||||||
int32_t length;
|
int32_t length;
|
||||||
|
|
||||||
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +111,7 @@ Locale::getDisplayScript(const Locale &displayLocale,
|
||||||
|
|
||||||
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
||||||
buffer=result.getBuffer(length);
|
buffer=result.getBuffer(length);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +139,7 @@ Locale::getDisplayCountry(const Locale &displayLocale,
|
||||||
int32_t length;
|
int32_t length;
|
||||||
|
|
||||||
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +151,7 @@ Locale::getDisplayCountry(const Locale &displayLocale,
|
||||||
|
|
||||||
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
||||||
buffer=result.getBuffer(length);
|
buffer=result.getBuffer(length);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +179,7 @@ Locale::getDisplayVariant(const Locale &displayLocale,
|
||||||
int32_t length;
|
int32_t length;
|
||||||
|
|
||||||
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +191,7 @@ Locale::getDisplayVariant(const Locale &displayLocale,
|
||||||
|
|
||||||
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
||||||
buffer=result.getBuffer(length);
|
buffer=result.getBuffer(length);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +219,7 @@ Locale::getDisplayName(const Locale &displayLocale,
|
||||||
int32_t length;
|
int32_t length;
|
||||||
|
|
||||||
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +231,7 @@ Locale::getDisplayName(const Locale &displayLocale,
|
||||||
|
|
||||||
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
|
||||||
buffer=result.getBuffer(length);
|
buffer=result.getBuffer(length);
|
||||||
if(buffer==0) {
|
if (buffer == nullptr) {
|
||||||
result.truncate(0);
|
result.truncate(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -276,50 +275,53 @@ U_NAMESPACE_END
|
||||||
|
|
||||||
U_NAMESPACE_USE
|
U_NAMESPACE_USE
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/* ### Constants **************************************************/
|
/* ### Constants **************************************************/
|
||||||
|
|
||||||
/* These strings describe the resources we attempt to load from
|
/* These strings describe the resources we attempt to load from
|
||||||
the locale ResourceBundle data file.*/
|
the locale ResourceBundle data file.*/
|
||||||
static const char _kLanguages[] = "Languages";
|
constexpr char _kLanguages[] = "Languages";
|
||||||
static const char _kScripts[] = "Scripts";
|
constexpr char _kScripts[] = "Scripts";
|
||||||
static const char _kScriptsStandAlone[] = "Scripts%stand-alone";
|
constexpr char _kScriptsStandAlone[] = "Scripts%stand-alone";
|
||||||
static const char _kCountries[] = "Countries";
|
constexpr char _kCountries[] = "Countries";
|
||||||
static const char _kVariants[] = "Variants";
|
constexpr char _kVariants[] = "Variants";
|
||||||
static const char _kKeys[] = "Keys";
|
constexpr char _kKeys[] = "Keys";
|
||||||
static const char _kTypes[] = "Types";
|
constexpr char _kTypes[] = "Types";
|
||||||
//static const char _kRootName[] = "root";
|
//constexpr char _kRootName[] = "root";
|
||||||
static const char _kCurrency[] = "currency";
|
constexpr char _kCurrency[] = "currency";
|
||||||
static const char _kCurrencies[] = "Currencies";
|
constexpr char _kCurrencies[] = "Currencies";
|
||||||
static const char _kLocaleDisplayPattern[] = "localeDisplayPattern";
|
constexpr char _kLocaleDisplayPattern[] = "localeDisplayPattern";
|
||||||
static const char _kPattern[] = "pattern";
|
constexpr char _kPattern[] = "pattern";
|
||||||
static const char _kSeparator[] = "separator";
|
constexpr char _kSeparator[] = "separator";
|
||||||
|
|
||||||
/* ### Display name **************************************************/
|
/* ### Display name **************************************************/
|
||||||
|
|
||||||
static int32_t
|
int32_t
|
||||||
_getStringOrCopyKey(const char *path, const char *locale,
|
_getStringOrCopyKey(const char *path, const char *locale,
|
||||||
const char *tableKey,
|
const char *tableKey,
|
||||||
const char* subTableKey,
|
const char* subTableKey,
|
||||||
const char *itemKey,
|
const char *itemKey,
|
||||||
const char *substitute,
|
const char *substitute,
|
||||||
char16_t *dest, int32_t destCapacity,
|
char16_t *dest, int32_t destCapacity,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode &errorCode) {
|
||||||
|
if (U_FAILURE(errorCode)) { return 0; }
|
||||||
const char16_t *s = nullptr;
|
const char16_t *s = nullptr;
|
||||||
int32_t length = 0;
|
int32_t length = 0;
|
||||||
|
|
||||||
if(itemKey==nullptr) {
|
if(itemKey==nullptr) {
|
||||||
/* top-level item: normal resource bundle access */
|
/* top-level item: normal resource bundle access */
|
||||||
icu::LocalUResourceBundlePointer rb(ures_open(path, locale, pErrorCode));
|
icu::LocalUResourceBundlePointer rb(ures_open(path, locale, &errorCode));
|
||||||
|
|
||||||
if(U_SUCCESS(*pErrorCode)) {
|
if(U_SUCCESS(errorCode)) {
|
||||||
s=ures_getStringByKey(rb.getAlias(), tableKey, &length, pErrorCode);
|
s=ures_getStringByKey(rb.getAlias(), tableKey, &length, &errorCode);
|
||||||
/* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
|
/* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool isLanguageCode = (uprv_strncmp(tableKey, _kLanguages, 9) == 0);
|
bool isLanguageCode = (uprv_strncmp(tableKey, _kLanguages, 9) == 0);
|
||||||
/* Language code should not be a number. If it is, set the error code. */
|
/* Language code should not be a number. If it is, set the error code. */
|
||||||
if (isLanguageCode && uprv_strtol(itemKey, nullptr, 10)) {
|
if (isLanguageCode && uprv_strtol(itemKey, nullptr, 10)) {
|
||||||
*pErrorCode = U_MISSING_RESOURCE_ERROR;
|
errorCode = U_MISSING_RESOURCE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
/* second-level item, use special fallback */
|
/* second-level item, use special fallback */
|
||||||
s=uloc_getTableStringWithFallback(path, locale,
|
s=uloc_getTableStringWithFallback(path, locale,
|
||||||
|
@ -327,22 +329,22 @@ _getStringOrCopyKey(const char *path, const char *locale,
|
||||||
subTableKey,
|
subTableKey,
|
||||||
itemKey,
|
itemKey,
|
||||||
&length,
|
&length,
|
||||||
pErrorCode);
|
&errorCode);
|
||||||
if (U_FAILURE(*pErrorCode) && isLanguageCode && itemKey != nullptr) {
|
if (U_FAILURE(errorCode) && isLanguageCode && itemKey != nullptr) {
|
||||||
// convert itemKey locale code to canonical form and try again, ICU-20870
|
// convert itemKey locale code to canonical form and try again, ICU-20870
|
||||||
*pErrorCode = U_ZERO_ERROR;
|
errorCode = U_ZERO_ERROR;
|
||||||
Locale canonKey = Locale::createCanonical(itemKey);
|
Locale canonKey = Locale::createCanonical(itemKey);
|
||||||
s=uloc_getTableStringWithFallback(path, locale,
|
s=uloc_getTableStringWithFallback(path, locale,
|
||||||
tableKey,
|
tableKey,
|
||||||
subTableKey,
|
subTableKey,
|
||||||
canonKey.getName(),
|
canonKey.getName(),
|
||||||
&length,
|
&length,
|
||||||
pErrorCode);
|
&errorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(U_SUCCESS(*pErrorCode)) {
|
if(U_SUCCESS(errorCode)) {
|
||||||
int32_t copyLength=uprv_min(length, destCapacity);
|
int32_t copyLength=uprv_min(length, destCapacity);
|
||||||
if(copyLength>0 && s != nullptr) {
|
if(copyLength>0 && s != nullptr) {
|
||||||
u_memcpy(dest, s, copyLength);
|
u_memcpy(dest, s, copyLength);
|
||||||
|
@ -351,67 +353,63 @@ _getStringOrCopyKey(const char *path, const char *locale,
|
||||||
/* no string from a resource bundle: convert the substitute */
|
/* no string from a resource bundle: convert the substitute */
|
||||||
length=(int32_t)uprv_strlen(substitute);
|
length=(int32_t)uprv_strlen(substitute);
|
||||||
u_charsToUChars(substitute, dest, uprv_min(length, destCapacity));
|
u_charsToUChars(substitute, dest, uprv_min(length, destCapacity));
|
||||||
*pErrorCode=U_USING_DEFAULT_WARNING;
|
errorCode = U_USING_DEFAULT_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return u_terminateUChars(dest, destCapacity, length, pErrorCode);
|
return u_terminateUChars(dest, destCapacity, length, &errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int32_t U_CALLCONV UDisplayNameGetter(const char *, char *, int32_t, UErrorCode *);
|
using UDisplayNameGetter = icu::CharString(const char*, UErrorCode&);
|
||||||
|
|
||||||
static int32_t
|
int32_t
|
||||||
_getDisplayNameForComponent(const char *locale,
|
_getDisplayNameForComponent(const char *locale,
|
||||||
const char *displayLocale,
|
const char *displayLocale,
|
||||||
char16_t *dest, int32_t destCapacity,
|
char16_t *dest, int32_t destCapacity,
|
||||||
UDisplayNameGetter *getter,
|
UDisplayNameGetter *getter,
|
||||||
const char *tag,
|
const char *tag,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode &errorCode) {
|
||||||
char localeBuffer[ULOC_FULLNAME_CAPACITY*4];
|
if (U_FAILURE(errorCode)) { return 0; }
|
||||||
int32_t length;
|
|
||||||
UErrorCode localStatus;
|
UErrorCode localStatus;
|
||||||
const char* root = nullptr;
|
const char* root = nullptr;
|
||||||
|
|
||||||
/* argument checking */
|
|
||||||
if(pErrorCode==nullptr || U_FAILURE(*pErrorCode)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destCapacity<0 || (destCapacity>0 && dest==nullptr)) {
|
if(destCapacity<0 || (destCapacity>0 && dest==nullptr)) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
localStatus = U_ZERO_ERROR;
|
localStatus = U_ZERO_ERROR;
|
||||||
length=(*getter)(locale, localeBuffer, sizeof(localeBuffer), &localStatus);
|
icu::CharString localeBuffer = (*getter)(locale, localStatus);
|
||||||
if(U_FAILURE(localStatus) || localStatus==U_STRING_NOT_TERMINATED_WARNING) {
|
if (U_FAILURE(localStatus)) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(length==0) {
|
if (localeBuffer.isEmpty()) {
|
||||||
// For the display name, we treat this as unknown language (ICU-20273).
|
// For the display name, we treat this as unknown language (ICU-20273).
|
||||||
if (getter == uloc_getLanguage) {
|
if (getter == ulocimp_getLanguage) {
|
||||||
uprv_strcpy(localeBuffer, "und");
|
localeBuffer.append("und", errorCode);
|
||||||
} else {
|
} else {
|
||||||
return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
|
return u_terminateUChars(dest, destCapacity, 0, &errorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root = tag == _kCountries ? U_ICUDATA_REGION : U_ICUDATA_LANG;
|
root = tag == _kCountries ? U_ICUDATA_REGION : U_ICUDATA_LANG;
|
||||||
|
|
||||||
return _getStringOrCopyKey(root, displayLocale,
|
return _getStringOrCopyKey(root, displayLocale,
|
||||||
tag, nullptr, localeBuffer,
|
tag, nullptr, localeBuffer.data(),
|
||||||
localeBuffer,
|
localeBuffer.data(),
|
||||||
dest, destCapacity,
|
dest, destCapacity,
|
||||||
pErrorCode);
|
errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
U_CAPI int32_t U_EXPORT2
|
U_CAPI int32_t U_EXPORT2
|
||||||
uloc_getDisplayLanguage(const char *locale,
|
uloc_getDisplayLanguage(const char *locale,
|
||||||
const char *displayLocale,
|
const char *displayLocale,
|
||||||
char16_t *dest, int32_t destCapacity,
|
char16_t *dest, int32_t destCapacity,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode *pErrorCode) {
|
||||||
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getLanguage, _kLanguages, pErrorCode);
|
ulocimp_getLanguage, _kLanguages, *pErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI int32_t U_EXPORT2
|
U_CAPI int32_t U_EXPORT2
|
||||||
|
@ -420,19 +418,20 @@ uloc_getDisplayScript(const char* locale,
|
||||||
char16_t *dest, int32_t destCapacity,
|
char16_t *dest, int32_t destCapacity,
|
||||||
UErrorCode *pErrorCode)
|
UErrorCode *pErrorCode)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(*pErrorCode)) { return 0; }
|
||||||
UErrorCode err = U_ZERO_ERROR;
|
UErrorCode err = U_ZERO_ERROR;
|
||||||
int32_t res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
int32_t res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getScript, _kScriptsStandAlone, &err);
|
ulocimp_getScript, _kScriptsStandAlone, err);
|
||||||
|
|
||||||
if (destCapacity == 0 && err == U_BUFFER_OVERFLOW_ERROR) {
|
if (destCapacity == 0 && err == U_BUFFER_OVERFLOW_ERROR) {
|
||||||
// For preflight, return the max of the value and the fallback.
|
// For preflight, return the max of the value and the fallback.
|
||||||
int32_t fallback_res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
int32_t fallback_res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getScript, _kScripts, pErrorCode);
|
ulocimp_getScript, _kScripts, *pErrorCode);
|
||||||
return (fallback_res > res) ? fallback_res : res;
|
return (fallback_res > res) ? fallback_res : res;
|
||||||
}
|
}
|
||||||
if ( err == U_USING_DEFAULT_WARNING ) {
|
if ( err == U_USING_DEFAULT_WARNING ) {
|
||||||
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getScript, _kScripts, pErrorCode);
|
ulocimp_getScript, _kScripts, *pErrorCode);
|
||||||
} else {
|
} else {
|
||||||
*pErrorCode = err;
|
*pErrorCode = err;
|
||||||
return res;
|
return res;
|
||||||
|
@ -446,7 +445,7 @@ uloc_getDisplayScriptInContext(const char* locale,
|
||||||
UErrorCode *pErrorCode)
|
UErrorCode *pErrorCode)
|
||||||
{
|
{
|
||||||
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getScript, _kScripts, pErrorCode);
|
ulocimp_getScript, _kScripts, *pErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI int32_t U_EXPORT2
|
U_CAPI int32_t U_EXPORT2
|
||||||
|
@ -455,7 +454,7 @@ uloc_getDisplayCountry(const char *locale,
|
||||||
char16_t *dest, int32_t destCapacity,
|
char16_t *dest, int32_t destCapacity,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode *pErrorCode) {
|
||||||
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getCountry, _kCountries, pErrorCode);
|
ulocimp_getRegion, _kCountries, *pErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -469,7 +468,7 @@ uloc_getDisplayVariant(const char *locale,
|
||||||
char16_t *dest, int32_t destCapacity,
|
char16_t *dest, int32_t destCapacity,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode *pErrorCode) {
|
||||||
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
|
||||||
uloc_getVariant, _kVariants, pErrorCode);
|
ulocimp_getVariant, _kVariants, *pErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Instead of having a separate pass for 'special' patterns, reintegrate the two
|
/* Instead of having a separate pass for 'special' patterns, reintegrate the two
|
||||||
|
@ -809,7 +808,7 @@ uloc_getDisplayKeyword(const char* keyword,
|
||||||
keyword,
|
keyword,
|
||||||
keyword,
|
keyword,
|
||||||
dest, destCapacity,
|
dest, destCapacity,
|
||||||
status);
|
*status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,11 +835,7 @@ uloc_getDisplayKeywordValue( const char* locale,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the keyword value */
|
/* get the keyword value */
|
||||||
CharString keywordValue;
|
CharString keywordValue = ulocimp_getKeywordValue(locale, keyword, *status);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&keywordValue);
|
|
||||||
ulocimp_getKeywordValue(locale, keyword, sink, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if the keyword is equal to currency .. then to get the display name
|
* if the keyword is equal to currency .. then to get the display name
|
||||||
|
@ -897,6 +892,6 @@ uloc_getDisplayKeywordValue( const char* locale,
|
||||||
keywordValue.data(),
|
keywordValue.data(),
|
||||||
keywordValue.data(),
|
keywordValue.data(),
|
||||||
dest, destCapacity,
|
dest, destCapacity,
|
||||||
status);
|
*status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ UBool U_CALLCONV cleanup() {
|
||||||
void U_CALLCONV LocaleDistance::initLocaleDistance(UErrorCode &errorCode) {
|
void U_CALLCONV LocaleDistance::initLocaleDistance(UErrorCode &errorCode) {
|
||||||
// This function is invoked only via umtx_initOnce().
|
// This function is invoked only via umtx_initOnce().
|
||||||
U_ASSERT(gLocaleDistance == nullptr);
|
U_ASSERT(gLocaleDistance == nullptr);
|
||||||
const XLikelySubtags &likely = *XLikelySubtags::getSingleton(errorCode);
|
const LikelySubtags &likely = *LikelySubtags::getSingleton(errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return; }
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
const LocaleDistanceData &data = likely.getDistanceData();
|
const LocaleDistanceData &data = likely.getDistanceData();
|
||||||
if (data.distanceTrieBytes == nullptr ||
|
if (data.distanceTrieBytes == nullptr ||
|
||||||
|
@ -83,7 +83,7 @@ const LocaleDistance *LocaleDistance::getSingleton(UErrorCode &errorCode) {
|
||||||
return gLocaleDistance;
|
return gLocaleDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocaleDistance::LocaleDistance(const LocaleDistanceData &data, const XLikelySubtags &likely) :
|
LocaleDistance::LocaleDistance(const LocaleDistanceData &data, const LikelySubtags &likely) :
|
||||||
likelySubtags(likely),
|
likelySubtags(likely),
|
||||||
trie(data.distanceTrieBytes),
|
trie(data.distanceTrieBytes),
|
||||||
regionToPartitionsIndex(data.regionToPartitions), partitionArrays(data.partitions),
|
regionToPartitionsIndex(data.regionToPartitions), partitionArrays(data.partitions),
|
||||||
|
@ -119,7 +119,7 @@ int32_t LocaleDistance::getBestIndexAndDistance(
|
||||||
uint64_t desLangState = desLangDistance >= 0 && supportedLSRsLength > 1 ? iter.getState64() : 0;
|
uint64_t desLangState = desLangDistance >= 0 && supportedLSRsLength > 1 ? iter.getState64() : 0;
|
||||||
// Index of the supported LSR with the lowest distance.
|
// Index of the supported LSR with the lowest distance.
|
||||||
int32_t bestIndex = -1;
|
int32_t bestIndex = -1;
|
||||||
// Cached lookup info from XLikelySubtags.compareLikely().
|
// Cached lookup info from LikelySubtags.compareLikely().
|
||||||
int32_t bestLikelyInfo = -1;
|
int32_t bestLikelyInfo = -1;
|
||||||
for (int32_t slIndex = 0; slIndex < supportedLSRsLength; ++slIndex) {
|
for (int32_t slIndex = 0; slIndex < supportedLSRsLength; ++slIndex) {
|
||||||
const LSR &supported = *supportedLSRs[slIndex];
|
const LSR &supported = *supportedLSRs[slIndex];
|
||||||
|
@ -399,7 +399,7 @@ int32_t LocaleDistance::trieNext(BytesTrie &iter, const char *s, bool wantValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool LocaleDistance::isParadigmLSR(const LSR &lsr) const {
|
bool LocaleDistance::isParadigmLSR(const LSR &lsr) const {
|
||||||
// Linear search for a very short list (length 6 as of 2019),
|
// Linear search for a very short list (length 6 as of 2019),
|
||||||
// because we look for equivalence not equality, and
|
// because we look for equivalence not equality, and
|
||||||
// because it's easy.
|
// because it's easy.
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
ULocMatchFavorSubtag favorSubtag,
|
ULocMatchFavorSubtag favorSubtag,
|
||||||
ULocMatchDirection direction) const;
|
ULocMatchDirection direction) const;
|
||||||
|
|
||||||
UBool isParadigmLSR(const LSR &lsr) const;
|
bool isParadigmLSR(const LSR &lsr) const;
|
||||||
|
|
||||||
int32_t getDefaultScriptDistance() const {
|
int32_t getDefaultScriptDistance() const {
|
||||||
return defaultScriptDistance;
|
return defaultScriptDistance;
|
||||||
|
@ -83,13 +83,13 @@ private:
|
||||||
// tic constexpr int32_t MAX_INDEX = 0x1fffff; // avoids sign bit
|
// tic constexpr int32_t MAX_INDEX = 0x1fffff; // avoids sign bit
|
||||||
static constexpr int32_t INDEX_NEG_1 = 0xfffffc00;
|
static constexpr int32_t INDEX_NEG_1 = 0xfffffc00;
|
||||||
|
|
||||||
LocaleDistance(const LocaleDistanceData &data, const XLikelySubtags &likely);
|
LocaleDistance(const LocaleDistanceData &data, const LikelySubtags &likely);
|
||||||
LocaleDistance(const LocaleDistance &other) = delete;
|
LocaleDistance(const LocaleDistance &other) = delete;
|
||||||
LocaleDistance &operator=(const LocaleDistance &other) = delete;
|
LocaleDistance &operator=(const LocaleDistance &other) = delete;
|
||||||
|
|
||||||
static void initLocaleDistance(UErrorCode &errorCode);
|
static void initLocaleDistance(UErrorCode &errorCode);
|
||||||
|
|
||||||
UBool isMatch(const LSR &desired, const LSR &supported,
|
bool isMatch(const LSR &desired, const LSR &supported,
|
||||||
int32_t shiftedThreshold, ULocMatchFavorSubtag favorSubtag) const {
|
int32_t shiftedThreshold, ULocMatchFavorSubtag favorSubtag) const {
|
||||||
const LSR *pSupp = &supported;
|
const LSR *pSupp = &supported;
|
||||||
return getBestIndexAndDistance(
|
return getBestIndexAndDistance(
|
||||||
|
@ -119,7 +119,7 @@ private:
|
||||||
return defaultRegionDistance;
|
return defaultRegionDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
const XLikelySubtags &likelySubtags;
|
const LikelySubtags &likelySubtags;
|
||||||
|
|
||||||
// The trie maps each dlang+slang+dscript+sscript+dregion+sregion
|
// The trie maps each dlang+slang+dscript+sscript+dregion+sregion
|
||||||
// (encoded in ASCII with bit 7 set on the last character of each subtag) to a distance.
|
// (encoded in ASCII with bit 7 set on the last character of each subtag) to a distance.
|
||||||
|
|
|
@ -18,45 +18,17 @@
|
||||||
#include "unicode/udisplaycontext.h"
|
#include "unicode/udisplaycontext.h"
|
||||||
#include "unicode/brkiter.h"
|
#include "unicode/brkiter.h"
|
||||||
#include "unicode/ucurr.h"
|
#include "unicode/ucurr.h"
|
||||||
|
#include "bytesinkutil.h"
|
||||||
|
#include "charstr.h"
|
||||||
#include "cmemory.h"
|
#include "cmemory.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
|
#include "uassert.h"
|
||||||
#include "ulocimp.h"
|
#include "ulocimp.h"
|
||||||
#include "umutex.h"
|
#include "umutex.h"
|
||||||
#include "ureslocs.h"
|
#include "ureslocs.h"
|
||||||
#include "uresimp.h"
|
#include "uresimp.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concatenate a number of null-terminated strings to buffer, leaving a
|
|
||||||
* null-terminated string. The last argument should be the null pointer.
|
|
||||||
* Return the length of the string in the buffer, not counting the trailing
|
|
||||||
* null. Return -1 if there is an error (buffer is null, or buflen < 1).
|
|
||||||
*/
|
|
||||||
static int32_t ncat(char *buffer, uint32_t buflen, ...) {
|
|
||||||
va_list args;
|
|
||||||
char *str;
|
|
||||||
char *p = buffer;
|
|
||||||
const char* e = buffer + buflen - 1;
|
|
||||||
|
|
||||||
if (buffer == nullptr || buflen < 1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(args, buflen);
|
|
||||||
while ((str = va_arg(args, char *)) != 0) {
|
|
||||||
char c;
|
|
||||||
while (p != e && (c = *str++) != 0) {
|
|
||||||
*p++ = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*p = 0;
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
return static_cast<int32_t>(p - buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -64,12 +36,13 @@ U_NAMESPACE_BEGIN
|
||||||
// Access resource data for locale components.
|
// Access resource data for locale components.
|
||||||
// Wrap code in uloc.c for now.
|
// Wrap code in uloc.c for now.
|
||||||
class ICUDataTable {
|
class ICUDataTable {
|
||||||
const char* path;
|
const char* const path;
|
||||||
Locale locale;
|
Locale locale;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Note: path should be a pointer to a statically allocated string.
|
||||||
ICUDataTable(const char* path, const Locale& locale);
|
ICUDataTable(const char* path, const Locale& locale);
|
||||||
~ICUDataTable();
|
~ICUDataTable() = default;
|
||||||
|
|
||||||
const Locale& getLocale();
|
const Locale& getLocale();
|
||||||
|
|
||||||
|
@ -95,23 +68,9 @@ ICUDataTable::getNoFallback(const char* tableKey, const char* itemKey, UnicodeSt
|
||||||
}
|
}
|
||||||
|
|
||||||
ICUDataTable::ICUDataTable(const char* path, const Locale& locale)
|
ICUDataTable::ICUDataTable(const char* path, const Locale& locale)
|
||||||
: path(nullptr), locale(Locale::getRoot())
|
: path(path), locale(locale)
|
||||||
{
|
{
|
||||||
if (path) {
|
U_ASSERT(path != nullptr);
|
||||||
int32_t len = static_cast<int32_t>(uprv_strlen(path));
|
|
||||||
this->path = (const char*) uprv_malloc(len + 1);
|
|
||||||
if (this->path) {
|
|
||||||
uprv_strcpy((char *)this->path, path);
|
|
||||||
this->locale = locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ICUDataTable::~ICUDataTable() {
|
|
||||||
if (path) {
|
|
||||||
uprv_free((void*) path);
|
|
||||||
path = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Locale&
|
const Locale&
|
||||||
|
@ -305,7 +264,7 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
|
||||||
};
|
};
|
||||||
// Capitalization transforms. For each usage type, indicates whether to titlecase for
|
// Capitalization transforms. For each usage type, indicates whether to titlecase for
|
||||||
// the context specified in capitalizationContext (which we know at construction time)
|
// the context specified in capitalizationContext (which we know at construction time)
|
||||||
UBool fCapitalization[kCapContextUsageCount];
|
bool fCapitalization[kCapContextUsageCount];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
|
@ -341,12 +300,12 @@ private:
|
||||||
UnicodeString& result, bool substitute) const;
|
UnicodeString& result, bool substitute) const;
|
||||||
UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
|
UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
|
||||||
UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString& result) const;
|
UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString& result) const;
|
||||||
UnicodeString& scriptDisplayName(const char* script, UnicodeString& result, UBool skipAdjust) const;
|
UnicodeString& scriptDisplayName(const char* script, UnicodeString& result, bool skipAdjust) const;
|
||||||
UnicodeString& regionDisplayName(const char* region, UnicodeString& result, UBool skipAdjust) const;
|
UnicodeString& regionDisplayName(const char* region, UnicodeString& result, bool skipAdjust) const;
|
||||||
UnicodeString& variantDisplayName(const char* variant, UnicodeString& result, UBool skipAdjust) const;
|
UnicodeString& variantDisplayName(const char* variant, UnicodeString& result, bool skipAdjust) const;
|
||||||
UnicodeString& keyDisplayName(const char* key, UnicodeString& result, UBool skipAdjust) const;
|
UnicodeString& keyDisplayName(const char* key, UnicodeString& result, bool skipAdjust) const;
|
||||||
UnicodeString& keyValueDisplayName(const char* key, const char* value,
|
UnicodeString& keyValueDisplayName(const char* key, const char* value,
|
||||||
UnicodeString& result, UBool skipAdjust) const;
|
UnicodeString& result, bool skipAdjust) const;
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
struct CapitalizationContextSink;
|
struct CapitalizationContextSink;
|
||||||
|
@ -399,7 +358,7 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocaleDisplayNamesImpl::CapitalizationContextSink : public ResourceSink {
|
struct LocaleDisplayNamesImpl::CapitalizationContextSink : public ResourceSink {
|
||||||
UBool hasCapitalizationUsage;
|
bool hasCapitalizationUsage;
|
||||||
LocaleDisplayNamesImpl& parent;
|
LocaleDisplayNamesImpl& parent;
|
||||||
|
|
||||||
CapitalizationContextSink(LocaleDisplayNamesImpl& _parent)
|
CapitalizationContextSink(LocaleDisplayNamesImpl& _parent)
|
||||||
|
@ -490,7 +449,7 @@ LocaleDisplayNamesImpl::initialize() {
|
||||||
#if !UCONFIG_NO_BREAK_ITERATION
|
#if !UCONFIG_NO_BREAK_ITERATION
|
||||||
// Only get the context data if we need it! This is a const object so we know now...
|
// Only get the context data if we need it! This is a const object so we know now...
|
||||||
// Also check whether we will need a break iterator (depends on the data)
|
// Also check whether we will need a break iterator (depends on the data)
|
||||||
UBool needBrkIter = false;
|
bool needBrkIter = false;
|
||||||
if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) {
|
if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) {
|
||||||
LocalUResourceBundlePointer resource(ures_open(nullptr, locale.getName(), &status));
|
LocalUResourceBundlePointer resource(ures_open(nullptr, locale.getName(), &status));
|
||||||
if (U_FAILURE(status)) { return; }
|
if (U_FAILURE(status)) { return; }
|
||||||
|
@ -582,38 +541,53 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
|
||||||
const char* country = loc.getCountry();
|
const char* country = loc.getCountry();
|
||||||
const char* variant = loc.getVariant();
|
const char* variant = loc.getVariant();
|
||||||
|
|
||||||
UBool hasScript = uprv_strlen(script) > 0;
|
bool hasScript = uprv_strlen(script) > 0;
|
||||||
UBool hasCountry = uprv_strlen(country) > 0;
|
bool hasCountry = uprv_strlen(country) > 0;
|
||||||
UBool hasVariant = uprv_strlen(variant) > 0;
|
bool hasVariant = uprv_strlen(variant) > 0;
|
||||||
|
|
||||||
if (dialectHandling == ULDN_DIALECT_NAMES) {
|
if (dialectHandling == ULDN_DIALECT_NAMES) {
|
||||||
char buffer[ULOC_FULLNAME_CAPACITY];
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
CharString buffer;
|
||||||
do { // loop construct is so we can break early out of search
|
do { // loop construct is so we can break early out of search
|
||||||
if (hasScript && hasCountry) {
|
if (hasScript && hasCountry) {
|
||||||
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0);
|
buffer.append(lang, status)
|
||||||
localeIdName(buffer, resultName, false);
|
.append('_', status)
|
||||||
|
.append(script, status)
|
||||||
|
.append('_', status)
|
||||||
|
.append(country, status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
localeIdName(buffer.data(), resultName, false);
|
||||||
if (!resultName.isBogus()) {
|
if (!resultName.isBogus()) {
|
||||||
hasScript = false;
|
hasScript = false;
|
||||||
hasCountry = false;
|
hasCountry = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (hasScript) {
|
if (hasScript) {
|
||||||
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
|
buffer.append(lang, status)
|
||||||
localeIdName(buffer, resultName, false);
|
.append('_', status)
|
||||||
|
.append(script, status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
localeIdName(buffer.data(), resultName, false);
|
||||||
if (!resultName.isBogus()) {
|
if (!resultName.isBogus()) {
|
||||||
hasScript = false;
|
hasScript = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (hasCountry) {
|
if (hasCountry) {
|
||||||
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
|
buffer.append(lang, status)
|
||||||
localeIdName(buffer, resultName, false);
|
.append('_', status)
|
||||||
|
.append(country, status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
localeIdName(buffer.data(), resultName, false);
|
||||||
if (!resultName.isBogus()) {
|
if (!resultName.isBogus()) {
|
||||||
hasCountry = false;
|
hasCountry = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} while (false);
|
} while (false);
|
||||||
}
|
}
|
||||||
if (resultName.isBogus() || resultName.isEmpty()) {
|
if (resultName.isBogus() || resultName.isEmpty()) {
|
||||||
|
@ -658,21 +632,19 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
|
||||||
LocalPointer<StringEnumeration> e(loc.createKeywords(status));
|
LocalPointer<StringEnumeration> e(loc.createKeywords(status));
|
||||||
if (e.isValid() && U_SUCCESS(status)) {
|
if (e.isValid() && U_SUCCESS(status)) {
|
||||||
UnicodeString temp2;
|
UnicodeString temp2;
|
||||||
char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY
|
|
||||||
const char* key;
|
const char* key;
|
||||||
while ((key = e->next((int32_t *)0, status)) != nullptr) {
|
while ((key = e->next((int32_t*)nullptr, status)) != nullptr) {
|
||||||
value[0] = 0;
|
auto value = loc.getKeywordValue<CharString>(key, status);
|
||||||
loc.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status);
|
if (U_FAILURE(status)) {
|
||||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
keyDisplayName(key, temp, true);
|
keyDisplayName(key, temp, true);
|
||||||
temp.findAndReplace(formatOpenParen, formatReplaceOpenParen);
|
temp.findAndReplace(formatOpenParen, formatReplaceOpenParen);
|
||||||
temp.findAndReplace(formatCloseParen, formatReplaceCloseParen);
|
temp.findAndReplace(formatCloseParen, formatReplaceCloseParen);
|
||||||
keyValueDisplayName(key, value, temp2, true);
|
keyValueDisplayName(key, value.data(), temp2, true);
|
||||||
temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen);
|
temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen);
|
||||||
temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen);
|
temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen);
|
||||||
if (temp2 != UnicodeString(value, -1, US_INV)) {
|
if (temp2 != UnicodeString(value.data(), -1, US_INV)) {
|
||||||
appendWithSep(resultRemainder, temp2);
|
appendWithSep(resultRemainder, temp2);
|
||||||
} else if (temp != UnicodeString(key, -1, US_INV)) {
|
} else if (temp != UnicodeString(key, -1, US_INV)) {
|
||||||
UnicodeString temp3;
|
UnicodeString temp3;
|
||||||
|
@ -779,7 +751,7 @@ LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
|
||||||
UnicodeString&
|
UnicodeString&
|
||||||
LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
|
LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
|
||||||
UnicodeString& result,
|
UnicodeString& result,
|
||||||
UBool skipAdjust) const {
|
bool skipAdjust) const {
|
||||||
if (nameLength == UDISPCTX_LENGTH_SHORT) {
|
if (nameLength == UDISPCTX_LENGTH_SHORT) {
|
||||||
langData.getNoFallback("Scripts%short", script, result);
|
langData.getNoFallback("Scripts%short", script, result);
|
||||||
if (!result.isBogus()) {
|
if (!result.isBogus()) {
|
||||||
|
@ -809,7 +781,7 @@ LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode,
|
||||||
UnicodeString&
|
UnicodeString&
|
||||||
LocaleDisplayNamesImpl::regionDisplayName(const char* region,
|
LocaleDisplayNamesImpl::regionDisplayName(const char* region,
|
||||||
UnicodeString& result,
|
UnicodeString& result,
|
||||||
UBool skipAdjust) const {
|
bool skipAdjust) const {
|
||||||
if (nameLength == UDISPCTX_LENGTH_SHORT) {
|
if (nameLength == UDISPCTX_LENGTH_SHORT) {
|
||||||
regionData.getNoFallback("Countries%short", region, result);
|
regionData.getNoFallback("Countries%short", region, result);
|
||||||
if (!result.isBogus()) {
|
if (!result.isBogus()) {
|
||||||
|
@ -834,7 +806,7 @@ LocaleDisplayNamesImpl::regionDisplayName(const char* region,
|
||||||
UnicodeString&
|
UnicodeString&
|
||||||
LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
|
LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
|
||||||
UnicodeString& result,
|
UnicodeString& result,
|
||||||
UBool skipAdjust) const {
|
bool skipAdjust) const {
|
||||||
// don't have a resource for short variant names
|
// don't have a resource for short variant names
|
||||||
if (substitute == UDISPCTX_SUBSTITUTE) {
|
if (substitute == UDISPCTX_SUBSTITUTE) {
|
||||||
langData.get("Variants", variant, result);
|
langData.get("Variants", variant, result);
|
||||||
|
@ -853,7 +825,7 @@ LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
|
||||||
UnicodeString&
|
UnicodeString&
|
||||||
LocaleDisplayNamesImpl::keyDisplayName(const char* key,
|
LocaleDisplayNamesImpl::keyDisplayName(const char* key,
|
||||||
UnicodeString& result,
|
UnicodeString& result,
|
||||||
UBool skipAdjust) const {
|
bool skipAdjust) const {
|
||||||
// don't have a resource for short key names
|
// don't have a resource for short key names
|
||||||
if (substitute == UDISPCTX_SUBSTITUTE) {
|
if (substitute == UDISPCTX_SUBSTITUTE) {
|
||||||
langData.get("Keys", key, result);
|
langData.get("Keys", key, result);
|
||||||
|
@ -873,7 +845,7 @@ UnicodeString&
|
||||||
LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
|
LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
|
||||||
const char* value,
|
const char* value,
|
||||||
UnicodeString& result,
|
UnicodeString& result,
|
||||||
UBool skipAdjust) const {
|
bool skipAdjust) const {
|
||||||
if (uprv_strcmp(key, "currency") == 0) {
|
if (uprv_strcmp(key, "currency") == 0) {
|
||||||
// ICU4C does not have ICU4J CurrencyDisplayInfo equivalent for now.
|
// ICU4C does not have ICU4J CurrencyDisplayInfo equivalent for now.
|
||||||
UErrorCode sts = U_ZERO_ERROR;
|
UErrorCode sts = U_ZERO_ERROR;
|
||||||
|
@ -939,7 +911,7 @@ uldn_open(const char * locale,
|
||||||
UDialectHandling dialectHandling,
|
UDialectHandling dialectHandling,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode *pErrorCode) {
|
||||||
if (U_FAILURE(*pErrorCode)) {
|
if (U_FAILURE(*pErrorCode)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (locale == nullptr) {
|
if (locale == nullptr) {
|
||||||
locale = uloc_getDefault();
|
locale = uloc_getDefault();
|
||||||
|
@ -952,7 +924,7 @@ uldn_openForContext(const char * locale,
|
||||||
UDisplayContext *contexts, int32_t length,
|
UDisplayContext *contexts, int32_t length,
|
||||||
UErrorCode *pErrorCode) {
|
UErrorCode *pErrorCode) {
|
||||||
if (U_FAILURE(*pErrorCode)) {
|
if (U_FAILURE(*pErrorCode)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (locale == nullptr) {
|
if (locale == nullptr) {
|
||||||
locale = uloc_getDefault();
|
locale = uloc_getDefault();
|
||||||
|
|
|
@ -57,10 +57,6 @@
|
||||||
#include "ustr_imp.h"
|
#include "ustr_imp.h"
|
||||||
#include "uvector.h"
|
#include "uvector.h"
|
||||||
|
|
||||||
U_CDECL_BEGIN
|
|
||||||
static UBool U_CALLCONV locale_cleanup();
|
|
||||||
U_CDECL_END
|
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
static Locale *gLocaleCache = nullptr;
|
static Locale *gLocaleCache = nullptr;
|
||||||
|
@ -106,16 +102,17 @@ typedef enum ELocalePos {
|
||||||
eMAX_LOCALES
|
eMAX_LOCALES
|
||||||
} ELocalePos;
|
} ELocalePos;
|
||||||
|
|
||||||
U_CDECL_BEGIN
|
namespace {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Deleter function for Locales owned by the default Locale hash table/
|
// Deleter function for Locales owned by the default Locale hash table/
|
||||||
//
|
//
|
||||||
static void U_CALLCONV
|
void U_CALLCONV
|
||||||
deleteLocale(void *obj) {
|
deleteLocale(void *obj) {
|
||||||
delete (icu::Locale *) obj;
|
delete (icu::Locale *) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool U_CALLCONV locale_cleanup()
|
UBool U_CALLCONV locale_cleanup()
|
||||||
{
|
{
|
||||||
U_NAMESPACE_USE
|
U_NAMESPACE_USE
|
||||||
|
|
||||||
|
@ -131,8 +128,7 @@ static UBool U_CALLCONV locale_cleanup()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void U_CALLCONV locale_init(UErrorCode &status) {
|
||||||
static void U_CALLCONV locale_init(UErrorCode &status) {
|
|
||||||
U_NAMESPACE_USE
|
U_NAMESPACE_USE
|
||||||
|
|
||||||
U_ASSERT(gLocaleCache == nullptr);
|
U_ASSERT(gLocaleCache == nullptr);
|
||||||
|
@ -163,7 +159,7 @@ static void U_CALLCONV locale_init(UErrorCode &status) {
|
||||||
gLocaleCache[eCANADA_FRENCH] = Locale("fr", "CA");
|
gLocaleCache[eCANADA_FRENCH] = Locale("fr", "CA");
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CDECL_END
|
} // namespace
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -182,15 +178,8 @@ Locale *locale_set_default_internal(const char *id, UErrorCode& status) {
|
||||||
canonicalize = true; // always canonicalize host ID
|
canonicalize = true; // always canonicalize host ID
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString localeNameBuf;
|
CharString localeNameBuf =
|
||||||
{
|
canonicalize ? ulocimp_canonicalize(id, status) : ulocimp_getName(id, status);
|
||||||
CharStringByteSink sink(&localeNameBuf);
|
|
||||||
if (canonicalize) {
|
|
||||||
ulocimp_canonicalize(id, sink, &status);
|
|
||||||
} else {
|
|
||||||
ulocimp_getName(id, sink, &status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return gDefaultLocale;
|
return gDefaultLocale;
|
||||||
|
@ -494,7 +483,7 @@ namespace {
|
||||||
UInitOnce gKnownCanonicalizedInitOnce {};
|
UInitOnce gKnownCanonicalizedInitOnce {};
|
||||||
UHashtable *gKnownCanonicalized = nullptr;
|
UHashtable *gKnownCanonicalized = nullptr;
|
||||||
|
|
||||||
static const char* const KNOWN_CANONICALIZED[] = {
|
constexpr const char* KNOWN_CANONICALIZED[] = {
|
||||||
"c",
|
"c",
|
||||||
// Commonly used locales known are already canonicalized
|
// Commonly used locales known are already canonicalized
|
||||||
"af", "af_ZA", "am", "am_ET", "ar", "ar_001", "as", "as_IN", "az", "az_AZ",
|
"af", "af_ZA", "am", "am_ET", "ar", "ar_001", "as", "as_IN", "az", "az_AZ",
|
||||||
|
@ -518,13 +507,13 @@ static const char* const KNOWN_CANONICALIZED[] = {
|
||||||
"zh_Hant_TW", "zh_TW", "zu", "zu_ZA"
|
"zh_Hant_TW", "zh_TW", "zu", "zu_ZA"
|
||||||
};
|
};
|
||||||
|
|
||||||
static UBool U_CALLCONV cleanupKnownCanonicalized() {
|
UBool U_CALLCONV cleanupKnownCanonicalized() {
|
||||||
gKnownCanonicalizedInitOnce.reset();
|
gKnownCanonicalizedInitOnce.reset();
|
||||||
if (gKnownCanonicalized) { uhash_close(gKnownCanonicalized); }
|
if (gKnownCanonicalized) { uhash_close(gKnownCanonicalized); }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void U_CALLCONV loadKnownCanonicalized(UErrorCode &status) {
|
void U_CALLCONV loadKnownCanonicalized(UErrorCode &status) {
|
||||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KNOWN_CANONICALIZED,
|
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KNOWN_CANONICALIZED,
|
||||||
cleanupKnownCanonicalized);
|
cleanupKnownCanonicalized);
|
||||||
LocalUHashtablePointer newKnownCanonicalizedMap(
|
LocalUHashtablePointer newKnownCanonicalizedMap(
|
||||||
|
@ -920,6 +909,8 @@ AliasData::loadData(UErrorCode &status)
|
||||||
*/
|
*/
|
||||||
AliasData*
|
AliasData*
|
||||||
AliasDataBuilder::build(UErrorCode &status) {
|
AliasDataBuilder::build(UErrorCode &status) {
|
||||||
|
if (U_FAILURE(status)) { return nullptr; }
|
||||||
|
|
||||||
LocalUResourceBundlePointer metadata(
|
LocalUResourceBundlePointer metadata(
|
||||||
ures_openDirect(nullptr, "metadata", &status));
|
ures_openDirect(nullptr, "metadata", &status));
|
||||||
LocalUResourceBundlePointer metadataAlias(
|
LocalUResourceBundlePointer metadataAlias(
|
||||||
|
@ -1065,7 +1056,7 @@ AliasDataBuilder::build(UErrorCode &status) {
|
||||||
*/
|
*/
|
||||||
class AliasReplacer {
|
class AliasReplacer {
|
||||||
public:
|
public:
|
||||||
AliasReplacer(UErrorCode status) :
|
AliasReplacer(UErrorCode& status) :
|
||||||
language(nullptr), script(nullptr), region(nullptr),
|
language(nullptr), script(nullptr), region(nullptr),
|
||||||
extensions(nullptr),
|
extensions(nullptr),
|
||||||
// store value in variants only once
|
// store value in variants only once
|
||||||
|
@ -1130,12 +1121,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather fields and generate locale ID into out.
|
// Gather fields and generate locale ID into out.
|
||||||
CharString& outputToString(CharString& out, UErrorCode status);
|
CharString& outputToString(CharString& out, UErrorCode& status);
|
||||||
|
|
||||||
// Generate the lookup key.
|
// Generate the lookup key.
|
||||||
CharString& generateKey(const char* language, const char* region,
|
CharString& generateKey(const char* language, const char* region,
|
||||||
const char* variant, CharString& out,
|
const char* variant, CharString& out,
|
||||||
UErrorCode status);
|
UErrorCode& status);
|
||||||
|
|
||||||
void parseLanguageReplacement(const char* replacement,
|
void parseLanguageReplacement(const char* replacement,
|
||||||
const char*& replaceLanguage,
|
const char*& replaceLanguage,
|
||||||
|
@ -1172,8 +1163,9 @@ private:
|
||||||
CharString&
|
CharString&
|
||||||
AliasReplacer::generateKey(
|
AliasReplacer::generateKey(
|
||||||
const char* language, const char* region, const char* variant,
|
const char* language, const char* region, const char* variant,
|
||||||
CharString& out, UErrorCode status)
|
CharString& out, UErrorCode& status)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return out; }
|
||||||
out.append(language, status);
|
out.append(language, status);
|
||||||
if (notEmpty(region)) {
|
if (notEmpty(region)) {
|
||||||
out.append(SEP_CHAR, status)
|
out.append(SEP_CHAR, status)
|
||||||
|
@ -1529,13 +1521,12 @@ AliasReplacer::replaceTransformedExtensions(
|
||||||
const char* tkey = ultag_getTKeyStart(str);
|
const char* tkey = ultag_getTKeyStart(str);
|
||||||
int32_t tlangLen = (tkey == str) ? 0 :
|
int32_t tlangLen = (tkey == str) ? 0 :
|
||||||
((tkey == nullptr) ? len : static_cast<int32_t>((tkey - str - 1)));
|
((tkey == nullptr) ? len : static_cast<int32_t>((tkey - str - 1)));
|
||||||
CharStringByteSink sink(&output);
|
|
||||||
if (tlangLen > 0) {
|
if (tlangLen > 0) {
|
||||||
Locale tlang = LocaleBuilder()
|
Locale tlang = LocaleBuilder()
|
||||||
.setLanguageTag(StringPiece(str, tlangLen))
|
.setLanguageTag(StringPiece(str, tlangLen))
|
||||||
.build(status);
|
.build(status);
|
||||||
tlang.canonicalize(status);
|
tlang.canonicalize(status);
|
||||||
tlang.toLanguageTag(sink, status);
|
output = tlang.toLanguageTag<CharString>(status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1591,8 +1582,9 @@ AliasReplacer::replaceTransformedExtensions(
|
||||||
|
|
||||||
CharString&
|
CharString&
|
||||||
AliasReplacer::outputToString(
|
AliasReplacer::outputToString(
|
||||||
CharString& out, UErrorCode status)
|
CharString& out, UErrorCode& status)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return out; }
|
||||||
out.append(language, status);
|
out.append(language, status);
|
||||||
if (notEmpty(script)) {
|
if (notEmpty(script)) {
|
||||||
out.append(SEP_CHAR, status)
|
out.append(SEP_CHAR, status)
|
||||||
|
@ -1735,9 +1727,7 @@ AliasReplacer::replace(const Locale& locale, CharString& out, UErrorCode& status
|
||||||
while ((key = iter->next(nullptr, status)) != nullptr) {
|
while ((key = iter->next(nullptr, status)) != nullptr) {
|
||||||
if (uprv_strcmp("sd", key) == 0 || uprv_strcmp("rg", key) == 0 ||
|
if (uprv_strcmp("sd", key) == 0 || uprv_strcmp("rg", key) == 0 ||
|
||||||
uprv_strcmp("t", key) == 0) {
|
uprv_strcmp("t", key) == 0) {
|
||||||
CharString value;
|
auto value = locale.getKeywordValue<CharString>(key, status);
|
||||||
CharStringByteSink valueSink(&value);
|
|
||||||
locale.getKeywordValue(key, valueSink, status);
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1782,6 +1772,7 @@ AliasReplacer::replace(const Locale& locale, CharString& out, UErrorCode& status
|
||||||
bool
|
bool
|
||||||
canonicalizeLocale(const Locale& locale, CharString& out, UErrorCode& status)
|
canonicalizeLocale(const Locale& locale, CharString& out, UErrorCode& status)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return false; }
|
||||||
AliasReplacer replacer(status);
|
AliasReplacer replacer(status);
|
||||||
return replacer.replace(locale, out, status);
|
return replacer.replace(locale, out, status);
|
||||||
}
|
}
|
||||||
|
@ -1791,6 +1782,8 @@ canonicalizeLocale(const Locale& locale, CharString& out, UErrorCode& status)
|
||||||
bool
|
bool
|
||||||
isKnownCanonicalizedLocale(const char* locale, UErrorCode& status)
|
isKnownCanonicalizedLocale(const char* locale, UErrorCode& status)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return false; }
|
||||||
|
|
||||||
if ( uprv_strcmp(locale, "c") == 0 ||
|
if ( uprv_strcmp(locale, "c") == 0 ||
|
||||||
uprv_strcmp(locale, "en") == 0 ||
|
uprv_strcmp(locale, "en") == 0 ||
|
||||||
uprv_strcmp(locale, "en_US") == 0) {
|
uprv_strcmp(locale, "en_US") == 0) {
|
||||||
|
@ -1809,24 +1802,30 @@ isKnownCanonicalizedLocale(const char* locale, UErrorCode& status)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
U_NAMESPACE_END
|
||||||
|
|
||||||
// Function for testing.
|
// Function for testing.
|
||||||
U_CAPI const char* const*
|
U_EXPORT const char* const*
|
||||||
ulocimp_getKnownCanonicalizedLocaleForTest(int32_t* length)
|
ulocimp_getKnownCanonicalizedLocaleForTest(int32_t& length)
|
||||||
{
|
{
|
||||||
*length = UPRV_LENGTHOF(KNOWN_CANONICALIZED);
|
U_NAMESPACE_USE
|
||||||
|
length = UPRV_LENGTHOF(KNOWN_CANONICALIZED);
|
||||||
return KNOWN_CANONICALIZED;
|
return KNOWN_CANONICALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for testing.
|
// Function for testing.
|
||||||
U_CAPI bool
|
U_EXPORT bool
|
||||||
ulocimp_isCanonicalizedLocaleForTest(const char* localeName)
|
ulocimp_isCanonicalizedLocaleForTest(const char* localeName)
|
||||||
{
|
{
|
||||||
|
U_NAMESPACE_USE
|
||||||
Locale l(localeName);
|
Locale l(localeName);
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
CharString temp;
|
CharString temp;
|
||||||
return !canonicalizeLocale(l, temp, status) && U_SUCCESS(status);
|
return !canonicalizeLocale(l, temp, status) && U_SUCCESS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/*This function initializes a Locale from a C locale ID*/
|
/*This function initializes a Locale from a C locale ID*/
|
||||||
Locale& Locale::init(const char* localeID, UBool canonicalize)
|
Locale& Locale::init(const char* localeID, UBool canonicalize)
|
||||||
{
|
{
|
||||||
|
@ -1846,7 +1845,7 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
|
||||||
// without goto and without another function
|
// without goto and without another function
|
||||||
do {
|
do {
|
||||||
char *separator;
|
char *separator;
|
||||||
char *field[5] = {0};
|
char *field[5] = {nullptr};
|
||||||
int32_t fieldLen[5] = {0};
|
int32_t fieldLen[5] = {0};
|
||||||
int32_t fieldIdx;
|
int32_t fieldIdx;
|
||||||
int32_t variantField;
|
int32_t variantField;
|
||||||
|
@ -1871,7 +1870,7 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
|
||||||
U_ASSERT(baseName == nullptr);
|
U_ASSERT(baseName == nullptr);
|
||||||
/*Go to heap for the fullName if necessary*/
|
/*Go to heap for the fullName if necessary*/
|
||||||
fullName = (char *)uprv_malloc(sizeof(char)*(length + 1));
|
fullName = (char *)uprv_malloc(sizeof(char)*(length + 1));
|
||||||
if(fullName == 0) {
|
if (fullName == nullptr) {
|
||||||
fullName = fullNameBuffer;
|
fullName = fullNameBuffer;
|
||||||
break; // error: out of memory
|
break; // error: out of memory
|
||||||
}
|
}
|
||||||
|
@ -1892,7 +1891,7 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
|
||||||
separator = field[0] = fullName;
|
separator = field[0] = fullName;
|
||||||
fieldIdx = 1;
|
fieldIdx = 1;
|
||||||
char* at = uprv_strchr(fullName, '@');
|
char* at = uprv_strchr(fullName, '@');
|
||||||
while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != 0 &&
|
while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != nullptr &&
|
||||||
fieldIdx < UPRV_LENGTHOF(field)-1 &&
|
fieldIdx < UPRV_LENGTHOF(field)-1 &&
|
||||||
(at == nullptr || separator < at)) {
|
(at == nullptr || separator < at)) {
|
||||||
field[fieldIdx] = separator + 1;
|
field[fieldIdx] = separator + 1;
|
||||||
|
@ -2074,11 +2073,7 @@ Locale::addLikelySubtags(UErrorCode& status) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString maximizedLocaleID;
|
CharString maximizedLocaleID = ulocimp_addLikelySubtags(fullName, status);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&maximizedLocaleID);
|
|
||||||
ulocimp_addLikelySubtags(fullName, sink, &status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
|
@ -2100,11 +2095,7 @@ Locale::minimizeSubtags(bool favorScript, UErrorCode& status) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString minimizedLocaleID;
|
CharString minimizedLocaleID = ulocimp_minimizeSubtags(fullName, favorScript, status);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&minimizedLocaleID);
|
|
||||||
ulocimp_minimizeSubtags(fullName, sink, favorScript, &status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
|
@ -2155,17 +2146,12 @@ Locale::forLanguageTag(StringPiece tag, UErrorCode& status)
|
||||||
// parsing. Therefore the code here explicitly calls uloc_forLanguageTag()
|
// parsing. Therefore the code here explicitly calls uloc_forLanguageTag()
|
||||||
// and then Locale::init(), instead of just calling the normal constructor.
|
// and then Locale::init(), instead of just calling the normal constructor.
|
||||||
|
|
||||||
CharString localeID;
|
|
||||||
int32_t parsedLength;
|
int32_t parsedLength;
|
||||||
{
|
CharString localeID = ulocimp_forLanguageTag(
|
||||||
CharStringByteSink sink(&localeID);
|
|
||||||
ulocimp_forLanguageTag(
|
|
||||||
tag.data(),
|
tag.data(),
|
||||||
tag.length(),
|
tag.length(),
|
||||||
sink,
|
|
||||||
&parsedLength,
|
&parsedLength,
|
||||||
&status);
|
status);
|
||||||
}
|
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -2195,7 +2181,7 @@ Locale::toLanguageTag(ByteSink& sink, UErrorCode& status) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulocimp_toLanguageTag(fullName, sink, /*strict=*/false, &status);
|
ulocimp_toLanguageTag(fullName, sink, /*strict=*/false, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
Locale U_EXPORT2
|
Locale U_EXPORT2
|
||||||
|
@ -2420,33 +2406,23 @@ Locale::getLocaleCache()
|
||||||
|
|
||||||
class KeywordEnumeration : public StringEnumeration {
|
class KeywordEnumeration : public StringEnumeration {
|
||||||
protected:
|
protected:
|
||||||
char *keywords;
|
CharString keywords;
|
||||||
private:
|
private:
|
||||||
char *current;
|
const char *current;
|
||||||
int32_t length;
|
static const char fgClassID;
|
||||||
UnicodeString currUSKey;
|
|
||||||
static const char fgClassID;/* Warning this is used beyond the typical RTTI usage. */
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static UClassID U_EXPORT2 getStaticClassID() { return (UClassID)&fgClassID; }
|
static UClassID U_EXPORT2 getStaticClassID() { return (UClassID)&fgClassID; }
|
||||||
virtual UClassID getDynamicClassID() const override { return getStaticClassID(); }
|
virtual UClassID getDynamicClassID() const override { return getStaticClassID(); }
|
||||||
public:
|
public:
|
||||||
KeywordEnumeration(const char *keys, int32_t keywordLen, int32_t currentIndex, UErrorCode &status)
|
KeywordEnumeration(const char *keys, int32_t keywordLen, int32_t currentIndex, UErrorCode &status)
|
||||||
: keywords((char *)&fgClassID), current((char *)&fgClassID), length(0) {
|
: keywords(), current(keywords.data()) {
|
||||||
if(U_SUCCESS(status) && keywordLen != 0) {
|
if(U_SUCCESS(status) && keywordLen != 0) {
|
||||||
if(keys == nullptr || keywordLen < 0) {
|
if(keys == nullptr || keywordLen < 0) {
|
||||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
} else {
|
} else {
|
||||||
keywords = (char *)uprv_malloc(keywordLen+1);
|
keywords.append(keys, keywordLen, status);
|
||||||
if (keywords == nullptr) {
|
current = keywords.data() + currentIndex;
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uprv_memcpy(keywords, keys, keywordLen);
|
|
||||||
keywords[keywordLen] = 0;
|
|
||||||
current = keywords + currentIndex;
|
|
||||||
length = keywordLen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2456,11 +2432,14 @@ public:
|
||||||
virtual StringEnumeration * clone() const override
|
virtual StringEnumeration * clone() const override
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
return new KeywordEnumeration(keywords, length, (int32_t)(current - keywords), status);
|
return new KeywordEnumeration(
|
||||||
|
keywords.data(), keywords.length(),
|
||||||
|
(int32_t)(current - keywords.data()), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int32_t count(UErrorCode &/*status*/) const override {
|
virtual int32_t count(UErrorCode& status) const override {
|
||||||
char *kw = keywords;
|
if (U_FAILURE(status)) { return 0; }
|
||||||
|
const char *kw = keywords.data();
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
while(*kw) {
|
while(*kw) {
|
||||||
result++;
|
result++;
|
||||||
|
@ -2489,21 +2468,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const UnicodeString* snext(UErrorCode& status) override {
|
virtual const UnicodeString* snext(UErrorCode& status) override {
|
||||||
|
if (U_FAILURE(status)) { return nullptr; }
|
||||||
int32_t resultLength = 0;
|
int32_t resultLength = 0;
|
||||||
const char *s = next(&resultLength, status);
|
const char *s = next(&resultLength, status);
|
||||||
return setChars(s, resultLength, status);
|
return setChars(s, resultLength, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void reset(UErrorCode& /*status*/) override {
|
virtual void reset(UErrorCode& status) override {
|
||||||
current = keywords;
|
if (U_FAILURE(status)) { return; }
|
||||||
|
current = keywords.data();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char KeywordEnumeration::fgClassID = '\0';
|
const char KeywordEnumeration::fgClassID = '\0';
|
||||||
|
|
||||||
KeywordEnumeration::~KeywordEnumeration() {
|
// Out-of-line virtual destructor to serve as the "key function".
|
||||||
uprv_free(keywords);
|
KeywordEnumeration::~KeywordEnumeration() = default;
|
||||||
}
|
|
||||||
|
|
||||||
// A wrapper around KeywordEnumeration that calls uloc_toUnicodeLocaleKey() in
|
// A wrapper around KeywordEnumeration that calls uloc_toUnicodeLocaleKey() in
|
||||||
// the next() method for each keyword before returning it.
|
// the next() method for each keyword before returning it.
|
||||||
|
@ -2528,8 +2508,9 @@ public:
|
||||||
if (resultLength != nullptr) *resultLength = 0;
|
if (resultLength != nullptr) *resultLength = 0;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
virtual int32_t count(UErrorCode &/*status*/) const override {
|
virtual int32_t count(UErrorCode& status) const override {
|
||||||
char *kw = keywords;
|
if (U_FAILURE(status)) { return 0; }
|
||||||
|
const char *kw = keywords.data();
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
while(*kw) {
|
while(*kw) {
|
||||||
if (uloc_toUnicodeLocaleKey(kw) != nullptr) {
|
if (uloc_toUnicodeLocaleKey(kw) != nullptr) {
|
||||||
|
@ -2557,9 +2538,7 @@ Locale::createKeywords(UErrorCode &status) const
|
||||||
const char* assignment = uprv_strchr(fullName, '=');
|
const char* assignment = uprv_strchr(fullName, '=');
|
||||||
if(variantStart) {
|
if(variantStart) {
|
||||||
if(assignment > variantStart) {
|
if(assignment > variantStart) {
|
||||||
CharString keywords;
|
CharString keywords = ulocimp_getKeywords(variantStart + 1, '@', false, status);
|
||||||
CharStringByteSink sink(&keywords);
|
|
||||||
ulocimp_getKeywords(variantStart+1, '@', sink, false, &status);
|
|
||||||
if (U_SUCCESS(status) && !keywords.isEmpty()) {
|
if (U_SUCCESS(status) && !keywords.isEmpty()) {
|
||||||
result = new KeywordEnumeration(keywords.data(), keywords.length(), 0, status);
|
result = new KeywordEnumeration(keywords.data(), keywords.length(), 0, status);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -2586,9 +2565,7 @@ Locale::createUnicodeKeywords(UErrorCode &status) const
|
||||||
const char* assignment = uprv_strchr(fullName, '=');
|
const char* assignment = uprv_strchr(fullName, '=');
|
||||||
if(variantStart) {
|
if(variantStart) {
|
||||||
if(assignment > variantStart) {
|
if(assignment > variantStart) {
|
||||||
CharString keywords;
|
CharString keywords = ulocimp_getKeywords(variantStart + 1, '@', false, status);
|
||||||
CharStringByteSink sink(&keywords);
|
|
||||||
ulocimp_getKeywords(variantStart+1, '@', sink, false, &status);
|
|
||||||
if (U_SUCCESS(status) && !keywords.isEmpty()) {
|
if (U_SUCCESS(status) && !keywords.isEmpty()) {
|
||||||
result = new UnicodeKeywordEnumeration(keywords.data(), keywords.length(), 0, status);
|
result = new UnicodeKeywordEnumeration(keywords.data(), keywords.length(), 0, status);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -2625,13 +2602,17 @@ Locale::getKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& sta
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulocimp_getKeywordValue(fullName, keywordName_nul.data(), sink, &status);
|
ulocimp_getKeywordValue(fullName, keywordName_nul.data(), sink, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Locale::getUnicodeKeywordValue(StringPiece keywordName,
|
Locale::getUnicodeKeywordValue(StringPiece keywordName,
|
||||||
ByteSink& sink,
|
ByteSink& sink,
|
||||||
UErrorCode& status) const {
|
UErrorCode& status) const {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Remove the need for a const char* to a NUL terminated buffer.
|
// TODO: Remove the need for a const char* to a NUL terminated buffer.
|
||||||
const CharString keywordName_nul(keywordName, status);
|
const CharString keywordName_nul(keywordName, status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
|
@ -2639,17 +2620,12 @@ Locale::getUnicodeKeywordValue(StringPiece keywordName,
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* legacy_key = uloc_toLegacyKey(keywordName_nul.data());
|
const char* legacy_key = uloc_toLegacyKey(keywordName_nul.data());
|
||||||
|
|
||||||
if (legacy_key == nullptr) {
|
if (legacy_key == nullptr) {
|
||||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString legacy_value;
|
auto legacy_value = getKeywordValue<CharString>(legacy_key, status);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&legacy_value);
|
|
||||||
getKeywordValue(legacy_key, sink, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
|
@ -2712,6 +2688,7 @@ void
|
||||||
Locale::setKeywordValue(StringPiece keywordName,
|
Locale::setKeywordValue(StringPiece keywordName,
|
||||||
StringPiece keywordValue,
|
StringPiece keywordValue,
|
||||||
UErrorCode& status) {
|
UErrorCode& status) {
|
||||||
|
if (U_FAILURE(status)) { return; }
|
||||||
// TODO: Remove the need for a const char* to a NUL terminated buffer.
|
// TODO: Remove the need for a const char* to a NUL terminated buffer.
|
||||||
const CharString keywordName_nul(keywordName, status);
|
const CharString keywordName_nul(keywordName, status);
|
||||||
const CharString keywordValue_nul(keywordValue, status);
|
const CharString keywordValue_nul(keywordValue, status);
|
||||||
|
@ -2722,16 +2699,18 @@ void
|
||||||
Locale::setUnicodeKeywordValue(StringPiece keywordName,
|
Locale::setUnicodeKeywordValue(StringPiece keywordName,
|
||||||
StringPiece keywordValue,
|
StringPiece keywordValue,
|
||||||
UErrorCode& status) {
|
UErrorCode& status) {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Remove the need for a const char* to a NUL terminated buffer.
|
// TODO: Remove the need for a const char* to a NUL terminated buffer.
|
||||||
const CharString keywordName_nul(keywordName, status);
|
const CharString keywordName_nul(keywordName, status);
|
||||||
const CharString keywordValue_nul(keywordValue, status);
|
const CharString keywordValue_nul(keywordValue, status);
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* legacy_key = uloc_toLegacyKey(keywordName_nul.data());
|
const char* legacy_key = uloc_toLegacyKey(keywordName_nul.data());
|
||||||
|
|
||||||
if (legacy_key == nullptr) {
|
if (legacy_key == nullptr) {
|
||||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
* that then do not depend on resource bundle code and likely-subtags data.
|
* that then do not depend on resource bundle code and likely-subtags data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "unicode/bytestream.h"
|
#include "unicode/bytestream.h"
|
||||||
#include "unicode/utypes.h"
|
#include "unicode/utypes.h"
|
||||||
#include "unicode/locid.h"
|
#include "unicode/locid.h"
|
||||||
|
@ -33,72 +35,31 @@
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
#include "loclikelysubtags.h"
|
#include "loclikelysubtags.h"
|
||||||
#include "ulocimp.h"
|
#include "ulocimp.h"
|
||||||
#include "ustr_imp.h"
|
|
||||||
|
|
||||||
/**
|
namespace {
|
||||||
* Append a tag to a buffer, adding the separator if necessary. The buffer
|
|
||||||
* must be large enough to contain the resulting tag plus any separator
|
|
||||||
* necessary. The tag must not be a zero-length string.
|
|
||||||
*
|
|
||||||
* @param tag The tag to add.
|
|
||||||
* @param tagLength The length of the tag.
|
|
||||||
* @param buffer The output buffer.
|
|
||||||
* @param bufferLength The length of the output buffer. This is an input/output parameter.
|
|
||||||
**/
|
|
||||||
static void U_CALLCONV
|
|
||||||
appendTag(
|
|
||||||
const char* tag,
|
|
||||||
int32_t tagLength,
|
|
||||||
char* buffer,
|
|
||||||
int32_t* bufferLength,
|
|
||||||
UBool withSeparator) {
|
|
||||||
|
|
||||||
if (withSeparator) {
|
|
||||||
buffer[*bufferLength] = '_';
|
|
||||||
++(*bufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
uprv_memmove(
|
|
||||||
&buffer[*bufferLength],
|
|
||||||
tag,
|
|
||||||
tagLength);
|
|
||||||
|
|
||||||
*bufferLength += tagLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a tag string from the supplied parameters. The lang, script and region
|
* Create a tag string from the supplied parameters. The lang, script and region
|
||||||
* parameters may be nullptr pointers. If they are, their corresponding length parameters
|
* parameters may be nullptr pointers. If they are, their corresponding length parameters
|
||||||
* must be less than or equal to 0.
|
* must be less than or equal to 0.
|
||||||
*
|
*
|
||||||
* If any of the language, script or region parameters are empty, and the alternateTags
|
|
||||||
* parameter is not nullptr, it will be parsed for potential language, script and region tags
|
|
||||||
* to be used when constructing the new tag. If the alternateTags parameter is nullptr, or
|
|
||||||
* it contains no language tag, the default tag for the unknown language is used.
|
|
||||||
*
|
|
||||||
* If the length of the new string exceeds the capacity of the output buffer,
|
|
||||||
* the function copies as many bytes to the output buffer as it can, and returns
|
|
||||||
* the error U_BUFFER_OVERFLOW_ERROR.
|
|
||||||
*
|
|
||||||
* If an illegal argument is provided, the function returns the error
|
* If an illegal argument is provided, the function returns the error
|
||||||
* U_ILLEGAL_ARGUMENT_ERROR.
|
* U_ILLEGAL_ARGUMENT_ERROR.
|
||||||
*
|
*
|
||||||
* Note that this function can return the warning U_STRING_NOT_TERMINATED_WARNING if
|
|
||||||
* the tag string fits in the output buffer, but the null terminator doesn't.
|
|
||||||
*
|
|
||||||
* @param lang The language tag to use.
|
* @param lang The language tag to use.
|
||||||
* @param langLength The length of the language tag.
|
* @param langLength The length of the language tag.
|
||||||
* @param script The script tag to use.
|
* @param script The script tag to use.
|
||||||
* @param scriptLength The length of the script tag.
|
* @param scriptLength The length of the script tag.
|
||||||
* @param region The region tag to use.
|
* @param region The region tag to use.
|
||||||
* @param regionLength The length of the region tag.
|
* @param regionLength The length of the region tag.
|
||||||
|
* @param variant The region tag to use.
|
||||||
|
* @param variantLength The length of the region tag.
|
||||||
* @param trailing Any trailing data to append to the new tag.
|
* @param trailing Any trailing data to append to the new tag.
|
||||||
* @param trailingLength The length of the trailing data.
|
* @param trailingLength The length of the trailing data.
|
||||||
* @param alternateTags A string containing any alternate tags.
|
|
||||||
* @param sink The output sink receiving the tag string.
|
* @param sink The output sink receiving the tag string.
|
||||||
* @param err A pointer to a UErrorCode for error reporting.
|
* @param err A pointer to a UErrorCode for error reporting.
|
||||||
**/
|
**/
|
||||||
static void U_CALLCONV
|
void U_CALLCONV
|
||||||
createTagStringWithAlternates(
|
createTagStringWithAlternates(
|
||||||
const char* lang,
|
const char* lang,
|
||||||
int32_t langLength,
|
int32_t langLength,
|
||||||
|
@ -106,392 +67,125 @@ createTagStringWithAlternates(
|
||||||
int32_t scriptLength,
|
int32_t scriptLength,
|
||||||
const char* region,
|
const char* region,
|
||||||
int32_t regionLength,
|
int32_t regionLength,
|
||||||
|
const char* variant,
|
||||||
|
int32_t variantLength,
|
||||||
const char* trailing,
|
const char* trailing,
|
||||||
int32_t trailingLength,
|
int32_t trailingLength,
|
||||||
const char* alternateTags,
|
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* err) {
|
UErrorCode& err) {
|
||||||
|
if (U_FAILURE(err)) {
|
||||||
if (U_FAILURE(*err)) {
|
return;
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
else if (langLength >= ULOC_LANG_CAPACITY ||
|
|
||||||
|
if (langLength >= ULOC_LANG_CAPACITY ||
|
||||||
scriptLength >= ULOC_SCRIPT_CAPACITY ||
|
scriptLength >= ULOC_SCRIPT_CAPACITY ||
|
||||||
regionLength >= ULOC_COUNTRY_CAPACITY) {
|
regionLength >= ULOC_COUNTRY_CAPACITY) {
|
||||||
goto error;
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
/**
|
|
||||||
* ULOC_FULLNAME_CAPACITY will provide enough capacity
|
|
||||||
* that we can build a string that contains the language,
|
|
||||||
* script and region code without worrying about overrunning
|
|
||||||
* the user-supplied buffer.
|
|
||||||
**/
|
|
||||||
char tagBuffer[ULOC_FULLNAME_CAPACITY];
|
|
||||||
int32_t tagLength = 0;
|
|
||||||
UBool regionAppended = false;
|
|
||||||
|
|
||||||
if (langLength > 0) {
|
if (langLength > 0) {
|
||||||
appendTag(
|
sink.Append(lang, langLength);
|
||||||
lang,
|
|
||||||
langLength,
|
|
||||||
tagBuffer,
|
|
||||||
&tagLength,
|
|
||||||
/*withSeparator=*/false);
|
|
||||||
}
|
|
||||||
else if (alternateTags == nullptr) {
|
|
||||||
/*
|
|
||||||
* Use the empty string for an unknown language, if
|
|
||||||
* we found no language.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*
|
|
||||||
* Parse the alternateTags string for the language.
|
|
||||||
*/
|
|
||||||
char alternateLang[ULOC_LANG_CAPACITY];
|
|
||||||
int32_t alternateLangLength = sizeof(alternateLang);
|
|
||||||
|
|
||||||
alternateLangLength =
|
|
||||||
uloc_getLanguage(
|
|
||||||
alternateTags,
|
|
||||||
alternateLang,
|
|
||||||
alternateLangLength,
|
|
||||||
err);
|
|
||||||
if(U_FAILURE(*err) ||
|
|
||||||
alternateLangLength >= ULOC_LANG_CAPACITY) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else if (alternateLangLength == 0) {
|
|
||||||
/*
|
|
||||||
* Use the empty string for an unknown language, if
|
|
||||||
* we found no language.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
appendTag(
|
|
||||||
alternateLang,
|
|
||||||
alternateLangLength,
|
|
||||||
tagBuffer,
|
|
||||||
&tagLength,
|
|
||||||
/*withSeparator=*/false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scriptLength > 0) {
|
if (scriptLength > 0) {
|
||||||
appendTag(
|
sink.Append("_", 1);
|
||||||
script,
|
sink.Append(script, scriptLength);
|
||||||
scriptLength,
|
|
||||||
tagBuffer,
|
|
||||||
&tagLength,
|
|
||||||
/*withSeparator=*/true);
|
|
||||||
}
|
|
||||||
else if (alternateTags != nullptr) {
|
|
||||||
/*
|
|
||||||
* Parse the alternateTags string for the script.
|
|
||||||
*/
|
|
||||||
char alternateScript[ULOC_SCRIPT_CAPACITY];
|
|
||||||
|
|
||||||
const int32_t alternateScriptLength =
|
|
||||||
uloc_getScript(
|
|
||||||
alternateTags,
|
|
||||||
alternateScript,
|
|
||||||
sizeof(alternateScript),
|
|
||||||
err);
|
|
||||||
|
|
||||||
if (U_FAILURE(*err) ||
|
|
||||||
alternateScriptLength >= ULOC_SCRIPT_CAPACITY) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else if (alternateScriptLength > 0) {
|
|
||||||
appendTag(
|
|
||||||
alternateScript,
|
|
||||||
alternateScriptLength,
|
|
||||||
tagBuffer,
|
|
||||||
&tagLength,
|
|
||||||
/*withSeparator=*/true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regionLength > 0) {
|
if (regionLength > 0) {
|
||||||
appendTag(
|
|
||||||
region,
|
|
||||||
regionLength,
|
|
||||||
tagBuffer,
|
|
||||||
&tagLength,
|
|
||||||
/*withSeparator=*/true);
|
|
||||||
|
|
||||||
regionAppended = true;
|
|
||||||
}
|
|
||||||
else if (alternateTags != nullptr) {
|
|
||||||
/*
|
|
||||||
* Parse the alternateTags string for the region.
|
|
||||||
*/
|
|
||||||
char alternateRegion[ULOC_COUNTRY_CAPACITY];
|
|
||||||
|
|
||||||
const int32_t alternateRegionLength =
|
|
||||||
uloc_getCountry(
|
|
||||||
alternateTags,
|
|
||||||
alternateRegion,
|
|
||||||
sizeof(alternateRegion),
|
|
||||||
err);
|
|
||||||
if (U_FAILURE(*err) ||
|
|
||||||
alternateRegionLength >= ULOC_COUNTRY_CAPACITY) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else if (alternateRegionLength > 0) {
|
|
||||||
appendTag(
|
|
||||||
alternateRegion,
|
|
||||||
alternateRegionLength,
|
|
||||||
tagBuffer,
|
|
||||||
&tagLength,
|
|
||||||
/*withSeparator=*/true);
|
|
||||||
|
|
||||||
regionAppended = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the partial tag from our internal buffer to the supplied
|
|
||||||
* target.
|
|
||||||
**/
|
|
||||||
sink.Append(tagBuffer, tagLength);
|
|
||||||
|
|
||||||
if (trailingLength > 0) {
|
|
||||||
if (*trailing != '@') {
|
|
||||||
sink.Append("_", 1);
|
sink.Append("_", 1);
|
||||||
if (!regionAppended) {
|
sink.Append(region, regionLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variantLength > 0) {
|
||||||
|
if (regionLength == 0) {
|
||||||
/* extra separator is required */
|
/* extra separator is required */
|
||||||
sink.Append("_", 1);
|
sink.Append("_", 1);
|
||||||
}
|
}
|
||||||
|
sink.Append("_", 1);
|
||||||
|
sink.Append(variant, variantLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trailingLength > 0) {
|
||||||
/*
|
/*
|
||||||
* Copy the trailing data into the supplied buffer.
|
* Copy the trailing data into the supplied buffer.
|
||||||
*/
|
*/
|
||||||
sink.Append(trailing, trailingLength);
|
sink.Append(trailing, trailingLength);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CHECK_TRAILING_VARIANT_SIZE(const char* variant, int32_t variantLength) {
|
||||||
|
int32_t count = 0;
|
||||||
|
for (int32_t i = 0; i < variantLength; i++) {
|
||||||
|
if (_isIDSeparator(variant[i])) {
|
||||||
|
count = 0;
|
||||||
|
} else if (count == 8) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_uloc_addLikelySubtags(const char* localeID,
|
||||||
|
icu::ByteSink& sink,
|
||||||
|
UErrorCode& err) {
|
||||||
|
if (U_FAILURE(err)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An overflow indicates the locale ID passed in
|
|
||||||
* is ill-formed. If we got here, and there was
|
|
||||||
* no previous error, it's an implicit overflow.
|
|
||||||
**/
|
|
||||||
if (*err == U_BUFFER_OVERFLOW_ERROR ||
|
|
||||||
U_SUCCESS(*err)) {
|
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the language, script, and region subtags from a tag string, and copy the
|
|
||||||
* results into the corresponding output parameters. The buffers are null-terminated,
|
|
||||||
* unless overflow occurs.
|
|
||||||
*
|
|
||||||
* The langLength, scriptLength, and regionLength parameters are input/output
|
|
||||||
* parameters, and must contain the capacity of their corresponding buffers on
|
|
||||||
* input. On output, they will contain the actual length of the buffers, not
|
|
||||||
* including the null terminator.
|
|
||||||
*
|
|
||||||
* If the length of any of the output subtags exceeds the capacity of the corresponding
|
|
||||||
* buffer, the function copies as many bytes to the output buffer as it can, and returns
|
|
||||||
* the error U_BUFFER_OVERFLOW_ERROR. It will not parse any more subtags once overflow
|
|
||||||
* occurs.
|
|
||||||
*
|
|
||||||
* If an illegal argument is provided, the function returns the error
|
|
||||||
* U_ILLEGAL_ARGUMENT_ERROR.
|
|
||||||
*
|
|
||||||
* @param localeID The locale ID to parse.
|
|
||||||
* @param lang The language tag buffer.
|
|
||||||
* @param langLength The length of the language tag.
|
|
||||||
* @param script The script tag buffer.
|
|
||||||
* @param scriptLength The length of the script tag.
|
|
||||||
* @param region The region tag buffer.
|
|
||||||
* @param regionLength The length of the region tag.
|
|
||||||
* @param err A pointer to a UErrorCode for error reporting.
|
|
||||||
* @return The number of chars of the localeID parameter consumed.
|
|
||||||
**/
|
|
||||||
static int32_t U_CALLCONV
|
|
||||||
parseTagString(
|
|
||||||
const char* localeID,
|
|
||||||
char* lang,
|
|
||||||
int32_t* langLength,
|
|
||||||
char* script,
|
|
||||||
int32_t* scriptLength,
|
|
||||||
char* region,
|
|
||||||
int32_t* regionLength,
|
|
||||||
UErrorCode* err)
|
|
||||||
{
|
|
||||||
const char* position = localeID;
|
|
||||||
int32_t subtagLength = 0;
|
|
||||||
|
|
||||||
if(U_FAILURE(*err) ||
|
|
||||||
localeID == nullptr ||
|
|
||||||
lang == nullptr ||
|
|
||||||
langLength == nullptr ||
|
|
||||||
script == nullptr ||
|
|
||||||
scriptLength == nullptr ||
|
|
||||||
region == nullptr ||
|
|
||||||
regionLength == nullptr) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
subtagLength = ulocimp_getLanguage(position, &position, *err).extract(lang, *langLength, *err);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING
|
|
||||||
* to be an error, because it indicates the user-supplied tag is
|
|
||||||
* not well-formed.
|
|
||||||
*/
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*langLength = subtagLength;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If no language was present, use the empty string instead.
|
|
||||||
* Otherwise, move past any separator.
|
|
||||||
*/
|
|
||||||
if (_isIDSeparator(*position)) {
|
|
||||||
++position;
|
|
||||||
}
|
|
||||||
|
|
||||||
subtagLength = ulocimp_getScript(position, &position, *err).extract(script, *scriptLength, *err);
|
|
||||||
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*scriptLength = subtagLength;
|
|
||||||
|
|
||||||
if (*scriptLength > 0) {
|
|
||||||
/*
|
|
||||||
* Move past any separator.
|
|
||||||
*/
|
|
||||||
if (_isIDSeparator(*position)) {
|
|
||||||
++position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subtagLength = ulocimp_getCountry(position, &position, *err).extract(region, *regionLength, *err);
|
|
||||||
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*regionLength = subtagLength;
|
|
||||||
|
|
||||||
if (*regionLength <= 0 && *position != 0 && *position != '@') {
|
|
||||||
/* back up over consumed trailing separator */
|
|
||||||
--position;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
|
|
||||||
return (int32_t)(position - localeID);
|
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we get here, we have no explicit error, it's the result of an
|
|
||||||
* illegal argument.
|
|
||||||
**/
|
|
||||||
if (!U_FAILURE(*err)) {
|
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) UPRV_BLOCK_MACRO_BEGIN { \
|
|
||||||
int32_t count = 0; \
|
|
||||||
int32_t i; \
|
|
||||||
for (i = 0; i < trailingLength; i++) { \
|
|
||||||
if (trailing[i] == '-' || trailing[i] == '_') { \
|
|
||||||
count = 0; \
|
|
||||||
if (count > 8) { \
|
|
||||||
goto error; \
|
|
||||||
} \
|
|
||||||
} else if (trailing[i] == '@') { \
|
|
||||||
break; \
|
|
||||||
} else if (count > 8) { \
|
|
||||||
goto error; \
|
|
||||||
} else { \
|
|
||||||
count++; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} UPRV_BLOCK_MACRO_END
|
|
||||||
|
|
||||||
static UBool
|
|
||||||
_uloc_addLikelySubtags(const char* localeID,
|
|
||||||
icu::ByteSink& sink,
|
|
||||||
UErrorCode* err) {
|
|
||||||
char lang[ULOC_LANG_CAPACITY];
|
|
||||||
int32_t langLength = sizeof(lang);
|
|
||||||
char script[ULOC_SCRIPT_CAPACITY];
|
|
||||||
int32_t scriptLength = sizeof(script);
|
|
||||||
char region[ULOC_COUNTRY_CAPACITY];
|
|
||||||
int32_t regionLength = sizeof(region);
|
|
||||||
const char* trailing = "";
|
|
||||||
int32_t trailingLength = 0;
|
|
||||||
int32_t trailingIndex = 0;
|
|
||||||
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (localeID == nullptr) {
|
if (localeID == nullptr) {
|
||||||
goto error;
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trailingIndex = parseTagString(
|
icu::CharString lang;
|
||||||
localeID,
|
icu::CharString script;
|
||||||
lang,
|
icu::CharString region;
|
||||||
&langLength,
|
icu::CharString variant;
|
||||||
script,
|
const char* trailing = nullptr;
|
||||||
&scriptLength,
|
ulocimp_getSubtags(localeID, &lang, &script, ®ion, &variant, &trailing, err);
|
||||||
region,
|
if (U_FAILURE(err)) {
|
||||||
®ionLength,
|
return;
|
||||||
err);
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
/* Overflow indicates an illegal argument error */
|
|
||||||
if (*err == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto error;
|
if (!CHECK_TRAILING_VARIANT_SIZE(variant.data(), variant.length())) {
|
||||||
}
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
if (langLength > 3) {
|
return;
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the length of the trailing portion. */
|
if (lang.length() == 4) {
|
||||||
while (_isIDSeparator(localeID[trailingIndex])) {
|
if (script.isEmpty()) {
|
||||||
trailingIndex++;
|
script = std::move(lang);
|
||||||
|
lang.clear();
|
||||||
|
} else {
|
||||||
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (lang.length() > 8) {
|
||||||
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
trailing = &localeID[trailingIndex];
|
|
||||||
trailingLength = (int32_t)uprv_strlen(trailing);
|
|
||||||
|
|
||||||
CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
|
int32_t trailingLength = (int32_t)uprv_strlen(trailing);
|
||||||
{
|
|
||||||
const icu::XLikelySubtags* likelySubtags = icu::XLikelySubtags::getSingleton(*err);
|
const icu::LikelySubtags* likelySubtags = icu::LikelySubtags::getSingleton(err);
|
||||||
if(U_FAILURE(*err)) {
|
if (U_FAILURE(err)) {
|
||||||
goto error;
|
return;
|
||||||
}
|
}
|
||||||
// We need to keep l on the stack because lsr may point into internal
|
// We need to keep l on the stack because lsr may point into internal
|
||||||
// memory of l.
|
// memory of l.
|
||||||
icu::Locale l = icu::Locale::createFromName(localeID);
|
icu::Locale l = icu::Locale::createFromName(localeID);
|
||||||
if (l.isBogus()) {
|
if (l.isBogus()) {
|
||||||
goto error;
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
icu::LSR lsr = likelySubtags->makeMaximizedLsrFrom(l, true, *err);
|
icu::LSR lsr = likelySubtags->makeMaximizedLsrFrom(l, true, err);
|
||||||
if(U_FAILURE(*err)) {
|
if (U_FAILURE(err)) {
|
||||||
goto error;
|
return;
|
||||||
}
|
}
|
||||||
const char* language = lsr.language;
|
const char* language = lsr.language;
|
||||||
if (uprv_strcmp(language, "und") == 0) {
|
if (uprv_strcmp(language, "und") == 0) {
|
||||||
|
@ -504,97 +198,57 @@ _uloc_addLikelySubtags(const char* localeID,
|
||||||
(int32_t)uprv_strlen(lsr.script),
|
(int32_t)uprv_strlen(lsr.script),
|
||||||
lsr.region,
|
lsr.region,
|
||||||
(int32_t)uprv_strlen(lsr.region),
|
(int32_t)uprv_strlen(lsr.region),
|
||||||
|
variant.data(),
|
||||||
|
variant.length(),
|
||||||
trailing,
|
trailing,
|
||||||
trailingLength,
|
trailingLength,
|
||||||
nullptr,
|
|
||||||
sink,
|
sink,
|
||||||
err);
|
err);
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
if (!U_FAILURE(*err)) {
|
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add likely subtags to the sink
|
void
|
||||||
// return true if the value in the sink is produced by a match during the lookup
|
|
||||||
// return false if the value in the sink is the same as input because there are
|
|
||||||
// no match after the lookup.
|
|
||||||
static UBool _ulocimp_addLikelySubtags(const char*, icu::ByteSink&, UErrorCode*);
|
|
||||||
|
|
||||||
static void
|
|
||||||
_uloc_minimizeSubtags(const char* localeID,
|
_uloc_minimizeSubtags(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
bool favorScript,
|
bool favorScript,
|
||||||
UErrorCode* err) {
|
UErrorCode& err) {
|
||||||
icu::CharString maximizedTagBuffer;
|
if (U_FAILURE(err)) {
|
||||||
|
return;
|
||||||
char lang[ULOC_LANG_CAPACITY];
|
|
||||||
int32_t langLength = sizeof(lang);
|
|
||||||
char script[ULOC_SCRIPT_CAPACITY];
|
|
||||||
int32_t scriptLength = sizeof(script);
|
|
||||||
char region[ULOC_COUNTRY_CAPACITY];
|
|
||||||
int32_t regionLength = sizeof(region);
|
|
||||||
const char* trailing = "";
|
|
||||||
int32_t trailingLength = 0;
|
|
||||||
int32_t trailingIndex = 0;
|
|
||||||
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else if (localeID == nullptr) {
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trailingIndex =
|
if (localeID == nullptr) {
|
||||||
parseTagString(
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
localeID,
|
return;
|
||||||
lang,
|
|
||||||
&langLength,
|
|
||||||
script,
|
|
||||||
&scriptLength,
|
|
||||||
region,
|
|
||||||
®ionLength,
|
|
||||||
err);
|
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
|
|
||||||
/* Overflow indicates an illegal argument error */
|
|
||||||
if (*err == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto error;
|
icu::CharString lang;
|
||||||
|
icu::CharString script;
|
||||||
|
icu::CharString region;
|
||||||
|
icu::CharString variant;
|
||||||
|
const char* trailing = nullptr;
|
||||||
|
ulocimp_getSubtags(localeID, &lang, &script, ®ion, &variant, &trailing, err);
|
||||||
|
if (U_FAILURE(err)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the spot where the variants or the keywords begin, if any. */
|
if (!CHECK_TRAILING_VARIANT_SIZE(variant.data(), variant.length())) {
|
||||||
while (_isIDSeparator(localeID[trailingIndex])) {
|
err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
trailingIndex++;
|
return;
|
||||||
}
|
}
|
||||||
trailing = &localeID[trailingIndex];
|
|
||||||
trailingLength = (int32_t)uprv_strlen(trailing);
|
|
||||||
|
|
||||||
CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
|
int32_t trailingLength = (int32_t)uprv_strlen(trailing);
|
||||||
|
|
||||||
{
|
const icu::LikelySubtags* likelySubtags = icu::LikelySubtags::getSingleton(err);
|
||||||
const icu::XLikelySubtags* likelySubtags = icu::XLikelySubtags::getSingleton(*err);
|
if (U_FAILURE(err)) {
|
||||||
if(U_FAILURE(*err)) {
|
return;
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
icu::LSR lsr = likelySubtags->minimizeSubtags(
|
icu::LSR lsr = likelySubtags->minimizeSubtags(
|
||||||
{lang, langLength},
|
lang.toStringPiece(),
|
||||||
{script, scriptLength},
|
script.toStringPiece(),
|
||||||
{region, regionLength},
|
region.toStringPiece(),
|
||||||
favorScript,
|
favorScript,
|
||||||
*err);
|
err);
|
||||||
if(U_FAILURE(*err)) {
|
if (U_FAILURE(err)) {
|
||||||
goto error;
|
return;
|
||||||
}
|
}
|
||||||
const char* language = lsr.language;
|
const char* language = lsr.language;
|
||||||
if (uprv_strcmp(language, "und") == 0) {
|
if (uprv_strcmp(language, "und") == 0) {
|
||||||
|
@ -607,74 +261,46 @@ _uloc_minimizeSubtags(const char* localeID,
|
||||||
(int32_t)uprv_strlen(lsr.script),
|
(int32_t)uprv_strlen(lsr.script),
|
||||||
lsr.region,
|
lsr.region,
|
||||||
(int32_t)uprv_strlen(lsr.region),
|
(int32_t)uprv_strlen(lsr.region),
|
||||||
|
variant.data(),
|
||||||
|
variant.length(),
|
||||||
trailing,
|
trailing,
|
||||||
trailingLength,
|
trailingLength,
|
||||||
nullptr,
|
|
||||||
sink,
|
sink,
|
||||||
err);
|
err);
|
||||||
if(U_FAILURE(*err)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
if (!U_FAILURE(*err)) {
|
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
U_CAPI int32_t U_EXPORT2
|
U_CAPI int32_t U_EXPORT2
|
||||||
uloc_addLikelySubtags(const char* localeID,
|
uloc_addLikelySubtags(const char* localeID,
|
||||||
char* maximizedLocaleID,
|
char* maximizedLocaleID,
|
||||||
int32_t maximizedLocaleIDCapacity,
|
int32_t maximizedLocaleIDCapacity,
|
||||||
UErrorCode* status) {
|
UErrorCode* status) {
|
||||||
if (U_FAILURE(*status)) {
|
return icu::ByteSinkUtil::viaByteSinkToTerminatedChars(
|
||||||
return 0;
|
maximizedLocaleID, maximizedLocaleIDCapacity,
|
||||||
}
|
[&](icu::ByteSink& sink, UErrorCode& status) {
|
||||||
|
|
||||||
icu::CheckedArrayByteSink sink(
|
|
||||||
maximizedLocaleID, maximizedLocaleIDCapacity);
|
|
||||||
|
|
||||||
ulocimp_addLikelySubtags(localeID, sink, status);
|
ulocimp_addLikelySubtags(localeID, sink, status);
|
||||||
int32_t reslen = sink.NumberOfBytesAppended();
|
},
|
||||||
|
*status);
|
||||||
if (U_FAILURE(*status)) {
|
|
||||||
return sink.Overflowed() ? reslen : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sink.Overflowed()) {
|
|
||||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
|
||||||
} else {
|
|
||||||
u_terminateChars(
|
|
||||||
maximizedLocaleID, maximizedLocaleIDCapacity, reslen, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
return reslen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool
|
U_EXPORT icu::CharString
|
||||||
_ulocimp_addLikelySubtags(const char* localeID,
|
ulocimp_addLikelySubtags(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
UErrorCode& status) {
|
||||||
UErrorCode* status) {
|
return icu::ByteSinkUtil::viaByteSinkToCharString(
|
||||||
icu::CharString localeBuffer;
|
[&](icu::ByteSink& sink, UErrorCode& status) {
|
||||||
{
|
ulocimp_addLikelySubtags(localeID, sink, status);
|
||||||
icu::CharStringByteSink localeSink(&localeBuffer);
|
},
|
||||||
ulocimp_canonicalize(localeID, localeSink, status);
|
status);
|
||||||
}
|
|
||||||
if (U_SUCCESS(*status)) {
|
|
||||||
return _uloc_addLikelySubtags(localeBuffer.data(), sink, status);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT void
|
||||||
ulocimp_addLikelySubtags(const char* localeID,
|
ulocimp_addLikelySubtags(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* status) {
|
UErrorCode& status) {
|
||||||
_ulocimp_addLikelySubtags(localeID, sink, status);
|
if (U_FAILURE(status)) { return; }
|
||||||
|
icu::CharString localeBuffer = ulocimp_canonicalize(localeID, status);
|
||||||
|
_uloc_addLikelySubtags(localeBuffer.data(), sink, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI int32_t U_EXPORT2
|
U_CAPI int32_t U_EXPORT2
|
||||||
|
@ -682,40 +308,32 @@ uloc_minimizeSubtags(const char* localeID,
|
||||||
char* minimizedLocaleID,
|
char* minimizedLocaleID,
|
||||||
int32_t minimizedLocaleIDCapacity,
|
int32_t minimizedLocaleIDCapacity,
|
||||||
UErrorCode* status) {
|
UErrorCode* status) {
|
||||||
if (U_FAILURE(*status)) {
|
return icu::ByteSinkUtil::viaByteSinkToTerminatedChars(
|
||||||
return 0;
|
minimizedLocaleID, minimizedLocaleIDCapacity,
|
||||||
}
|
[&](icu::ByteSink& sink, UErrorCode& status) {
|
||||||
|
|
||||||
icu::CheckedArrayByteSink sink(
|
|
||||||
minimizedLocaleID, minimizedLocaleIDCapacity);
|
|
||||||
|
|
||||||
ulocimp_minimizeSubtags(localeID, sink, false, status);
|
ulocimp_minimizeSubtags(localeID, sink, false, status);
|
||||||
int32_t reslen = sink.NumberOfBytesAppended();
|
},
|
||||||
|
*status);
|
||||||
if (U_FAILURE(*status)) {
|
|
||||||
return sink.Overflowed() ? reslen : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sink.Overflowed()) {
|
|
||||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
|
||||||
} else {
|
|
||||||
u_terminateChars(
|
|
||||||
minimizedLocaleID, minimizedLocaleIDCapacity, reslen, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
return reslen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_minimizeSubtags(const char* localeID,
|
||||||
|
bool favorScript,
|
||||||
|
UErrorCode& status) {
|
||||||
|
return icu::ByteSinkUtil::viaByteSinkToCharString(
|
||||||
|
[&](icu::ByteSink& sink, UErrorCode& status) {
|
||||||
|
ulocimp_minimizeSubtags(localeID, sink, favorScript, status);
|
||||||
|
},
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
ulocimp_minimizeSubtags(const char* localeID,
|
ulocimp_minimizeSubtags(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
bool favorScript,
|
bool favorScript,
|
||||||
UErrorCode* status) {
|
UErrorCode& status) {
|
||||||
icu::CharString localeBuffer;
|
if (U_FAILURE(status)) { return; }
|
||||||
{
|
icu::CharString localeBuffer = ulocimp_canonicalize(localeID, status);
|
||||||
icu::CharStringByteSink localeSink(&localeBuffer);
|
|
||||||
ulocimp_canonicalize(localeID, localeSink, status);
|
|
||||||
}
|
|
||||||
_uloc_minimizeSubtags(localeBuffer.data(), sink, favorScript, status);
|
_uloc_minimizeSubtags(localeBuffer.data(), sink, favorScript, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,22 +346,16 @@ static const char LANG_DIR_STRING[] =
|
||||||
U_CAPI UBool U_EXPORT2
|
U_CAPI UBool U_EXPORT2
|
||||||
uloc_isRightToLeft(const char *locale) {
|
uloc_isRightToLeft(const char *locale) {
|
||||||
UErrorCode errorCode = U_ZERO_ERROR;
|
UErrorCode errorCode = U_ZERO_ERROR;
|
||||||
char script[8];
|
icu::CharString lang;
|
||||||
int32_t scriptLength = uloc_getScript(locale, script, UPRV_LENGTHOF(script), &errorCode);
|
icu::CharString script;
|
||||||
if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING ||
|
ulocimp_getSubtags(locale, &lang, &script, nullptr, nullptr, nullptr, errorCode);
|
||||||
scriptLength == 0) {
|
if (U_FAILURE(errorCode) || script.isEmpty()) {
|
||||||
// Fastpath: We know the likely scripts and their writing direction
|
// Fastpath: We know the likely scripts and their writing direction
|
||||||
// for some common languages.
|
// for some common languages.
|
||||||
errorCode = U_ZERO_ERROR;
|
if (!lang.isEmpty()) {
|
||||||
char lang[8];
|
const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang.data());
|
||||||
int32_t langLength = uloc_getLanguage(locale, lang, UPRV_LENGTHOF(lang), &errorCode);
|
|
||||||
if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (langLength > 0) {
|
|
||||||
const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang);
|
|
||||||
if (langPtr != nullptr) {
|
if (langPtr != nullptr) {
|
||||||
switch (langPtr[langLength]) {
|
switch (langPtr[lang.length()]) {
|
||||||
case '-': return false;
|
case '-': return false;
|
||||||
case '+': return true;
|
case '+': return true;
|
||||||
default: break; // partial match of a longer code
|
default: break; // partial match of a longer code
|
||||||
|
@ -752,21 +364,16 @@ uloc_isRightToLeft(const char *locale) {
|
||||||
}
|
}
|
||||||
// Otherwise, find the likely script.
|
// Otherwise, find the likely script.
|
||||||
errorCode = U_ZERO_ERROR;
|
errorCode = U_ZERO_ERROR;
|
||||||
icu::CharString likely;
|
icu::CharString likely = ulocimp_addLikelySubtags(locale, errorCode);
|
||||||
{
|
if (U_FAILURE(errorCode)) {
|
||||||
icu::CharStringByteSink sink(&likely);
|
|
||||||
ulocimp_addLikelySubtags(locale, sink, &errorCode);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
scriptLength = uloc_getScript(likely.data(), script, UPRV_LENGTHOF(script), &errorCode);
|
ulocimp_getSubtags(likely.data(), nullptr, &script, nullptr, nullptr, nullptr, errorCode);
|
||||||
if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING ||
|
if (U_FAILURE(errorCode) || script.isEmpty()) {
|
||||||
scriptLength == 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UScriptCode scriptCode = (UScriptCode)u_getPropertyValueEnum(UCHAR_SCRIPT, script);
|
UScriptCode scriptCode = (UScriptCode)u_getPropertyValueEnum(UCHAR_SCRIPT, script.data());
|
||||||
return uscript_isRightToLeft(scriptCode);
|
return uscript_isRightToLeft(scriptCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,65 +386,52 @@ Locale::isRightToLeft() const {
|
||||||
|
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
|
||||||
// The following must at least allow for rg key value (6) plus terminator (1).
|
namespace {
|
||||||
#define ULOC_RG_BUFLEN 8
|
icu::CharString
|
||||||
|
GetRegionFromKey(const char* localeID, const char* key, UErrorCode& status) {
|
||||||
|
icu::CharString result;
|
||||||
|
|
||||||
U_CAPI int32_t U_EXPORT2
|
// First check for keyword value
|
||||||
ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
|
icu::CharString kw = ulocimp_getKeywordValue(localeID, key, status);
|
||||||
char *region, int32_t regionCapacity, UErrorCode* status) {
|
int32_t len = kw.length();
|
||||||
if (U_FAILURE(*status)) {
|
if (U_SUCCESS(status) && len >= 3 && len <= 7) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
char rgBuf[ULOC_RG_BUFLEN];
|
|
||||||
UErrorCode rgStatus = U_ZERO_ERROR;
|
|
||||||
|
|
||||||
// First check for rg keyword value
|
|
||||||
icu::CharString rg;
|
|
||||||
{
|
|
||||||
icu::CharStringByteSink sink(&rg);
|
|
||||||
ulocimp_getKeywordValue(localeID, "rg", sink, &rgStatus);
|
|
||||||
}
|
|
||||||
int32_t rgLen = rg.length();
|
|
||||||
if (U_FAILURE(rgStatus) || rgLen < 3 || rgLen > 7) {
|
|
||||||
rgLen = 0;
|
|
||||||
} else {
|
|
||||||
// chop off the subdivision code (which will generally be "zzzz" anyway)
|
// chop off the subdivision code (which will generally be "zzzz" anyway)
|
||||||
const char* const data = rg.data();
|
const char* const data = kw.data();
|
||||||
if (uprv_isASCIILetter(data[0])) {
|
if (uprv_isASCIILetter(data[0])) {
|
||||||
rgLen = 2;
|
result.append(uprv_toupper(data[0]), status);
|
||||||
rgBuf[0] = uprv_toupper(data[0]);
|
result.append(uprv_toupper(data[1]), status);
|
||||||
rgBuf[1] = uprv_toupper(data[1]);
|
|
||||||
} else {
|
} else {
|
||||||
// assume three-digit region code
|
// assume three-digit region code
|
||||||
rgLen = 3;
|
result.append(data, 3, status);
|
||||||
uprv_memcpy(rgBuf, data, rgLen);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
if (rgLen == 0) {
|
|
||||||
// No valid rg keyword value, try for unicode_region_subtag
|
|
||||||
rgLen = uloc_getCountry(localeID, rgBuf, ULOC_RG_BUFLEN, status);
|
|
||||||
if (U_FAILURE(*status)) {
|
|
||||||
rgLen = 0;
|
|
||||||
} else if (rgLen == 0 && inferRegion) {
|
|
||||||
// no unicode_region_subtag but inferRegion true, try likely subtags
|
|
||||||
rgStatus = U_ZERO_ERROR;
|
|
||||||
icu::CharString locBuf;
|
|
||||||
{
|
|
||||||
icu::CharStringByteSink sink(&locBuf);
|
|
||||||
ulocimp_addLikelySubtags(localeID, sink, &rgStatus);
|
|
||||||
}
|
|
||||||
if (U_SUCCESS(rgStatus)) {
|
|
||||||
rgLen = uloc_getCountry(locBuf.data(), rgBuf, ULOC_RG_BUFLEN, status);
|
|
||||||
if (U_FAILURE(*status)) {
|
|
||||||
rgLen = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rgBuf[rgLen] = 0;
|
|
||||||
uprv_strncpy(region, rgBuf, regionCapacity);
|
|
||||||
return u_terminateChars(region, regionCapacity, rgLen, status);
|
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getRegionForSupplementalData(const char *localeID, bool inferRegion,
|
||||||
|
UErrorCode& status) {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
icu::CharString rgBuf = GetRegionFromKey(localeID, "rg", status);
|
||||||
|
if (U_SUCCESS(status) && rgBuf.isEmpty()) {
|
||||||
|
// No valid rg keyword value, try for unicode_region_subtag
|
||||||
|
rgBuf = ulocimp_getRegion(localeID, status);
|
||||||
|
if (U_SUCCESS(status) && rgBuf.isEmpty() && inferRegion) {
|
||||||
|
// Second check for sd keyword value
|
||||||
|
rgBuf = GetRegionFromKey(localeID, "sd", status);
|
||||||
|
if (U_SUCCESS(status) && rgBuf.isEmpty()) {
|
||||||
|
// no unicode_region_subtag but inferRegion true, try likely subtags
|
||||||
|
UErrorCode rgStatus = U_ZERO_ERROR;
|
||||||
|
icu::CharString locBuf = ulocimp_addLikelySubtags(localeID, rgStatus);
|
||||||
|
if (U_SUCCESS(rgStatus)) {
|
||||||
|
rgBuf = ulocimp_getRegion(locBuf.data(), status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rgBuf;
|
||||||
|
}
|
||||||
|
|
|
@ -51,8 +51,7 @@ LocaleDistanceData::~LocaleDistanceData() {
|
||||||
delete[] paradigms;
|
delete[] paradigms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ICU-20777): Rename to just LikelySubtagsData.
|
struct LikelySubtagsData {
|
||||||
struct XLikelySubtagsData {
|
|
||||||
UResourceBundle *langInfoBundle = nullptr;
|
UResourceBundle *langInfoBundle = nullptr;
|
||||||
UniqueCharStrings strings;
|
UniqueCharStrings strings;
|
||||||
CharStringMap languageAliases;
|
CharStringMap languageAliases;
|
||||||
|
@ -63,14 +62,15 @@ struct XLikelySubtagsData {
|
||||||
|
|
||||||
LocaleDistanceData distanceData;
|
LocaleDistanceData distanceData;
|
||||||
|
|
||||||
XLikelySubtagsData(UErrorCode &errorCode) : strings(errorCode) {}
|
LikelySubtagsData(UErrorCode &errorCode) : strings(errorCode) {}
|
||||||
|
|
||||||
~XLikelySubtagsData() {
|
~LikelySubtagsData() {
|
||||||
ures_close(langInfoBundle);
|
ures_close(langInfoBundle);
|
||||||
delete[] lsrs;
|
delete[] lsrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(UErrorCode &errorCode) {
|
void load(UErrorCode &errorCode) {
|
||||||
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
langInfoBundle = ures_openDirect(nullptr, "langInfo", &errorCode);
|
langInfoBundle = ures_openDirect(nullptr, "langInfo", &errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return; }
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
StackUResourceBundle stackTempBundle;
|
StackUResourceBundle stackTempBundle;
|
||||||
|
@ -231,6 +231,7 @@ struct XLikelySubtagsData {
|
||||||
private:
|
private:
|
||||||
bool readStrings(const ResourceTable &table, const char *key, ResourceValue &value,
|
bool readStrings(const ResourceTable &table, const char *key, ResourceValue &value,
|
||||||
LocalMemory<int32_t> &indexes, int32_t &length, UErrorCode &errorCode) {
|
LocalMemory<int32_t> &indexes, int32_t &length, UErrorCode &errorCode) {
|
||||||
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
if (table.findValue(key, value)) {
|
if (table.findValue(key, value)) {
|
||||||
ResourceArray stringArray = value.getArray(errorCode);
|
ResourceArray stringArray = value.getArray(errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return false; }
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
|
@ -297,7 +298,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
UnicodeString toRegion(const ResourceArray& m49Array, ResourceValue &value, int encoded, UErrorCode &errorCode) {
|
UnicodeString toRegion(const ResourceArray& m49Array, ResourceValue &value, int encoded, UErrorCode &errorCode) {
|
||||||
if (encoded == 0 || encoded == 1) {
|
if (U_FAILURE(errorCode) || encoded == 0 || encoded == 1) {
|
||||||
return UNICODE_STRING_SIMPLE("");
|
return UNICODE_STRING_SIMPLE("");
|
||||||
}
|
}
|
||||||
encoded &= 0x00ffffff;
|
encoded &= 0x00ffffff;
|
||||||
|
@ -315,6 +316,7 @@ private:
|
||||||
|
|
||||||
bool readLSREncodedStrings(const ResourceTable &table, const char* key, ResourceValue &value, const ResourceArray& m49Array,
|
bool readLSREncodedStrings(const ResourceTable &table, const char* key, ResourceValue &value, const ResourceArray& m49Array,
|
||||||
LocalMemory<int32_t> &indexes, int32_t &length, UErrorCode &errorCode) {
|
LocalMemory<int32_t> &indexes, int32_t &length, UErrorCode &errorCode) {
|
||||||
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
if (table.findValue(key, value)) {
|
if (table.findValue(key, value)) {
|
||||||
const int32_t* vectors = value.getIntVector(length, errorCode);
|
const int32_t* vectors = value.getIntVector(length, errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return false; }
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
|
@ -339,7 +341,7 @@ private:
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
XLikelySubtags *gLikelySubtags = nullptr;
|
LikelySubtags *gLikelySubtags = nullptr;
|
||||||
UVector *gMacroregions = nullptr;
|
UVector *gMacroregions = nullptr;
|
||||||
UInitOnce gInitOnce {};
|
UInitOnce gInitOnce {};
|
||||||
|
|
||||||
|
@ -352,21 +354,36 @@ UBool U_CALLCONV cleanup() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char16_t RANGE_MARKER = 0x7E; /* '~' */
|
constexpr const char16_t* MACROREGION_HARDCODE[] = {
|
||||||
UVector* loadMacroregions(UErrorCode &status) {
|
u"001~3",
|
||||||
LocalPointer<UVector> newMacroRegions(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
|
u"005",
|
||||||
|
u"009",
|
||||||
|
u"011",
|
||||||
|
u"013~5",
|
||||||
|
u"017~9",
|
||||||
|
u"021",
|
||||||
|
u"029",
|
||||||
|
u"030",
|
||||||
|
u"034~5",
|
||||||
|
u"039",
|
||||||
|
u"053~4",
|
||||||
|
u"057",
|
||||||
|
u"061",
|
||||||
|
u"142~3",
|
||||||
|
u"145",
|
||||||
|
u"150~1",
|
||||||
|
u"154~5",
|
||||||
|
u"202",
|
||||||
|
u"419",
|
||||||
|
u"EU",
|
||||||
|
u"EZ",
|
||||||
|
u"QO",
|
||||||
|
u"UN",
|
||||||
|
};
|
||||||
|
|
||||||
LocalUResourceBundlePointer supplementalData(ures_openDirect(nullptr,"supplementalData",&status));
|
constexpr char16_t RANGE_MARKER = 0x7E; /* '~' */
|
||||||
LocalUResourceBundlePointer idValidity(ures_getByKey(supplementalData.getAlias(),"idValidity",nullptr,&status));
|
void processMacroregionRange(const UnicodeString& regionName, UVector* newMacroRegions, UErrorCode& status) {
|
||||||
LocalUResourceBundlePointer regionList(ures_getByKey(idValidity.getAlias(),"region",nullptr,&status));
|
if (U_FAILURE(status)) { return; }
|
||||||
LocalUResourceBundlePointer regionMacro(ures_getByKey(regionList.getAlias(),"macroregion",nullptr,&status));
|
|
||||||
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (U_SUCCESS(status) && ures_hasNext(regionMacro.getAlias())) {
|
|
||||||
UnicodeString regionName = ures_getNextUnicodeString(regionMacro.getAlias(),nullptr,&status);
|
|
||||||
int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER);
|
int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER);
|
||||||
char16_t buf[6];
|
char16_t buf[6];
|
||||||
regionName.extract(buf,6,status);
|
regionName.extract(buf,6,status);
|
||||||
|
@ -382,20 +399,68 @@ UVector* loadMacroregions(UErrorCode &status) {
|
||||||
LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
|
LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
|
||||||
newMacroRegions->adoptElement(newRegion.orphan(),status);
|
newMacroRegions->adoptElement(newRegion.orphan(),status);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if U_DEBUG
|
||||||
|
UVector* loadMacroregions(UErrorCode &status) {
|
||||||
|
if (U_FAILURE(status)) { return nullptr; }
|
||||||
|
LocalPointer<UVector> newMacroRegions(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
|
||||||
|
|
||||||
|
LocalUResourceBundlePointer supplementalData(ures_openDirect(nullptr,"supplementalData",&status));
|
||||||
|
LocalUResourceBundlePointer idValidity(ures_getByKey(supplementalData.getAlias(),"idValidity",nullptr,&status));
|
||||||
|
LocalUResourceBundlePointer regionList(ures_getByKey(idValidity.getAlias(),"region",nullptr,&status));
|
||||||
|
LocalUResourceBundlePointer regionMacro(ures_getByKey(regionList.getAlias(),"macroregion",nullptr,&status));
|
||||||
|
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (ures_hasNext(regionMacro.getAlias())) {
|
||||||
|
UnicodeString regionName = ures_getNextUnicodeString(regionMacro.getAlias(),nullptr,&status);
|
||||||
|
processMacroregionRange(regionName, newMacroRegions.getAlias(), status);
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newMacroRegions.orphan();
|
||||||
|
}
|
||||||
|
#endif // U_DEBUG
|
||||||
|
|
||||||
|
UVector* getStaticMacroregions(UErrorCode &status) {
|
||||||
|
if (U_FAILURE(status)) { return nullptr; }
|
||||||
|
LocalPointer<UVector> newMacroRegions(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
|
||||||
|
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto *region : MACROREGION_HARDCODE) {
|
||||||
|
UnicodeString regionName(region);
|
||||||
|
processMacroregionRange(regionName, newMacroRegions.getAlias(), status);
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return newMacroRegions.orphan();
|
return newMacroRegions.orphan();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void U_CALLCONV XLikelySubtags::initLikelySubtags(UErrorCode &errorCode) {
|
void U_CALLCONV LikelySubtags::initLikelySubtags(UErrorCode &errorCode) {
|
||||||
// This function is invoked only via umtx_initOnce().
|
// This function is invoked only via umtx_initOnce().
|
||||||
U_ASSERT(gLikelySubtags == nullptr);
|
U_ASSERT(gLikelySubtags == nullptr);
|
||||||
XLikelySubtagsData data(errorCode);
|
LikelySubtagsData data(errorCode);
|
||||||
data.load(errorCode);
|
data.load(errorCode);
|
||||||
if (U_FAILURE(errorCode)) { return; }
|
if (U_FAILURE(errorCode)) { return; }
|
||||||
gLikelySubtags = new XLikelySubtags(data);
|
gLikelySubtags = new LikelySubtags(data);
|
||||||
gMacroregions = loadMacroregions(errorCode);
|
gMacroregions = getStaticMacroregions(errorCode);
|
||||||
|
#if U_DEBUG
|
||||||
|
auto macroregionsFromData = loadMacroregions(errorCode);
|
||||||
|
U_ASSERT((*gMacroregions) == (*macroregionsFromData));
|
||||||
|
delete macroregionsFromData;
|
||||||
|
#endif
|
||||||
if (U_FAILURE(errorCode) || gLikelySubtags == nullptr || gMacroregions == nullptr) {
|
if (U_FAILURE(errorCode) || gLikelySubtags == nullptr || gMacroregions == nullptr) {
|
||||||
delete gLikelySubtags;
|
delete gLikelySubtags;
|
||||||
delete gMacroregions;
|
delete gMacroregions;
|
||||||
|
@ -406,13 +471,13 @@ void U_CALLCONV XLikelySubtags::initLikelySubtags(UErrorCode &errorCode) {
|
||||||
ucln_common_registerCleanup(UCLN_COMMON_LIKELY_SUBTAGS, cleanup);
|
ucln_common_registerCleanup(UCLN_COMMON_LIKELY_SUBTAGS, cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
const XLikelySubtags *XLikelySubtags::getSingleton(UErrorCode &errorCode) {
|
const LikelySubtags *LikelySubtags::getSingleton(UErrorCode &errorCode) {
|
||||||
if (U_FAILURE(errorCode)) { return nullptr; }
|
if (U_FAILURE(errorCode)) { return nullptr; }
|
||||||
umtx_initOnce(gInitOnce, &XLikelySubtags::initLikelySubtags, errorCode);
|
umtx_initOnce(gInitOnce, &LikelySubtags::initLikelySubtags, errorCode);
|
||||||
return gLikelySubtags;
|
return gLikelySubtags;
|
||||||
}
|
}
|
||||||
|
|
||||||
XLikelySubtags::XLikelySubtags(XLikelySubtagsData &data) :
|
LikelySubtags::LikelySubtags(LikelySubtagsData &data) :
|
||||||
langInfoBundle(data.langInfoBundle),
|
langInfoBundle(data.langInfoBundle),
|
||||||
strings(data.strings.orphanCharStrings()),
|
strings(data.strings.orphanCharStrings()),
|
||||||
languageAliases(std::move(data.languageAliases)),
|
languageAliases(std::move(data.languageAliases)),
|
||||||
|
@ -421,7 +486,7 @@ XLikelySubtags::XLikelySubtags(XLikelySubtagsData &data) :
|
||||||
lsrs(data.lsrs),
|
lsrs(data.lsrs),
|
||||||
#if U_DEBUG
|
#if U_DEBUG
|
||||||
lsrsLength(data.lsrsLength),
|
lsrsLength(data.lsrsLength),
|
||||||
#endif
|
#endif // U_DEBUG
|
||||||
distanceData(std::move(data.distanceData)) {
|
distanceData(std::move(data.distanceData)) {
|
||||||
data.langInfoBundle = nullptr;
|
data.langInfoBundle = nullptr;
|
||||||
data.lsrs = nullptr;
|
data.lsrs = nullptr;
|
||||||
|
@ -447,18 +512,19 @@ XLikelySubtags::XLikelySubtags(XLikelySubtagsData &data) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XLikelySubtags::~XLikelySubtags() {
|
LikelySubtags::~LikelySubtags() {
|
||||||
ures_close(langInfoBundle);
|
ures_close(langInfoBundle);
|
||||||
delete strings;
|
delete strings;
|
||||||
delete[] lsrs;
|
delete[] lsrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
LSR XLikelySubtags::makeMaximizedLsrFrom(const Locale &locale,
|
LSR LikelySubtags::makeMaximizedLsrFrom(const Locale &locale,
|
||||||
bool returnInputIfUnmatch,
|
bool returnInputIfUnmatch,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
if (locale.isBogus()) {
|
if (locale.isBogus()) {
|
||||||
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
|
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return LSR("", "", "", LSR::EXPLICIT_LSR);
|
return {};
|
||||||
}
|
}
|
||||||
const char *name = locale.getName();
|
const char *name = locale.getName();
|
||||||
if (uprv_isAtSign(name[0]) && name[1] == 'x' && name[2] == '=') { // name.startsWith("@x=")
|
if (uprv_isAtSign(name[0]) && name[1] == 'x' && name[2] == '=') { // name.startsWith("@x=")
|
||||||
|
@ -490,10 +556,11 @@ const char *getCanonical(const CharStringMap &aliases, const char *alias) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
LSR XLikelySubtags::makeMaximizedLsr(const char *language, const char *script, const char *region,
|
LSR LikelySubtags::makeMaximizedLsr(const char *language, const char *script, const char *region,
|
||||||
const char *variant,
|
const char *variant,
|
||||||
bool returnInputIfUnmatch,
|
bool returnInputIfUnmatch,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
// Handle pseudolocales like en-XA, ar-XB, fr-PSCRACK.
|
// Handle pseudolocales like en-XA, ar-XB, fr-PSCRACK.
|
||||||
// They should match only themselves,
|
// They should match only themselves,
|
||||||
// not other locales with what looks like the same language and script subtags.
|
// not other locales with what looks like the same language and script subtags.
|
||||||
|
@ -501,12 +568,21 @@ LSR XLikelySubtags::makeMaximizedLsr(const char *language, const char *script, c
|
||||||
if (region[0] == 'X' && (c1 = region[1]) != 0 && region[2] == 0) {
|
if (region[0] == 'X' && (c1 = region[1]) != 0 && region[2] == 0) {
|
||||||
switch (c1) {
|
switch (c1) {
|
||||||
case 'A':
|
case 'A':
|
||||||
|
if (returnInputIfUnmatch) {
|
||||||
|
return LSR(language, script, region, LSR::EXPLICIT_LSR);
|
||||||
|
}
|
||||||
return LSR(PSEUDO_ACCENTS_PREFIX, language, script, region,
|
return LSR(PSEUDO_ACCENTS_PREFIX, language, script, region,
|
||||||
LSR::EXPLICIT_LSR, errorCode);
|
LSR::EXPLICIT_LSR, errorCode);
|
||||||
case 'B':
|
case 'B':
|
||||||
|
if (returnInputIfUnmatch) {
|
||||||
|
return LSR(language, script, region, LSR::EXPLICIT_LSR);
|
||||||
|
}
|
||||||
return LSR(PSEUDO_BIDI_PREFIX, language, script, region,
|
return LSR(PSEUDO_BIDI_PREFIX, language, script, region,
|
||||||
LSR::EXPLICIT_LSR, errorCode);
|
LSR::EXPLICIT_LSR, errorCode);
|
||||||
case 'C':
|
case 'C':
|
||||||
|
if (returnInputIfUnmatch) {
|
||||||
|
return LSR(language, script, region, LSR::EXPLICIT_LSR);
|
||||||
|
}
|
||||||
return LSR(PSEUDO_CRACKED_PREFIX, language, script, region,
|
return LSR(PSEUDO_CRACKED_PREFIX, language, script, region,
|
||||||
LSR::EXPLICIT_LSR, errorCode);
|
LSR::EXPLICIT_LSR, errorCode);
|
||||||
default: // normal locale
|
default: // normal locale
|
||||||
|
@ -536,9 +612,10 @@ LSR XLikelySubtags::makeMaximizedLsr(const char *language, const char *script, c
|
||||||
return maximize(language, script, region, returnInputIfUnmatch, errorCode);
|
return maximize(language, script, region, returnInputIfUnmatch, errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
LSR XLikelySubtags::maximize(const char *language, const char *script, const char *region,
|
LSR LikelySubtags::maximize(const char *language, const char *script, const char *region,
|
||||||
bool returnInputIfUnmatch,
|
bool returnInputIfUnmatch,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return maximize({language, (int32_t)uprv_strlen(language)},
|
return maximize({language, (int32_t)uprv_strlen(language)},
|
||||||
{script, (int32_t)uprv_strlen(script)},
|
{script, (int32_t)uprv_strlen(script)},
|
||||||
{region, (int32_t)uprv_strlen(region)},
|
{region, (int32_t)uprv_strlen(region)},
|
||||||
|
@ -546,23 +623,21 @@ LSR XLikelySubtags::maximize(const char *language, const char *script, const cha
|
||||||
errorCode);
|
errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XLikelySubtags::isMacroregion(StringPiece& region, UErrorCode& errorCode) const {
|
bool LikelySubtags::isMacroregion(StringPiece& region, UErrorCode& errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
// In Java, we use Region class. In C++, since Region is under i18n,
|
// In Java, we use Region class. In C++, since Region is under i18n,
|
||||||
// we read the same data used by Region into gMacroregions avoid dependency
|
// we read the same data used by Region into gMacroregions avoid dependency
|
||||||
// from common to i18n/region.cpp
|
// from common to i18n/region.cpp
|
||||||
if (U_FAILURE(errorCode)) { return false; }
|
umtx_initOnce(gInitOnce, &LikelySubtags::initLikelySubtags, errorCode);
|
||||||
umtx_initOnce(gInitOnce, &XLikelySubtags::initLikelySubtags, errorCode);
|
|
||||||
if (U_FAILURE(errorCode)) { return false; }
|
if (U_FAILURE(errorCode)) { return false; }
|
||||||
UnicodeString str(UnicodeString::fromUTF8(region));
|
UnicodeString str(UnicodeString::fromUTF8(region));
|
||||||
return gMacroregions->contains((void *)&str);
|
return gMacroregions->contains((void *)&str);
|
||||||
}
|
}
|
||||||
|
|
||||||
LSR XLikelySubtags::maximize(StringPiece language, StringPiece script, StringPiece region,
|
LSR LikelySubtags::maximize(StringPiece language, StringPiece script, StringPiece region,
|
||||||
bool returnInputIfUnmatch,
|
bool returnInputIfUnmatch,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return LSR(language, script, region, LSR::EXPLICIT_LSR, errorCode);
|
|
||||||
}
|
|
||||||
if (language.compare("und") == 0) {
|
if (language.compare("und") == 0) {
|
||||||
language = "";
|
language = "";
|
||||||
}
|
}
|
||||||
|
@ -681,7 +756,7 @@ LSR XLikelySubtags::maximize(StringPiece language, StringPiece script, StringPie
|
||||||
return LSR(language, script, region, retainMask, errorCode);
|
return LSR(language, script, region, retainMask, errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t XLikelySubtags::compareLikely(const LSR &lsr, const LSR &other, int32_t likelyInfo) const {
|
int32_t LikelySubtags::compareLikely(const LSR &lsr, const LSR &other, int32_t likelyInfo) const {
|
||||||
// If likelyInfo >= 0:
|
// If likelyInfo >= 0:
|
||||||
// likelyInfo bit 1 is set if the previous comparison with lsr
|
// likelyInfo bit 1 is set if the previous comparison with lsr
|
||||||
// was for equal language and script.
|
// was for equal language and script.
|
||||||
|
@ -723,7 +798,7 @@ int32_t XLikelySubtags::compareLikely(const LSR &lsr, const LSR &other, int32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subset of maximize().
|
// Subset of maximize().
|
||||||
int32_t XLikelySubtags::getLikelyIndex(const char *language, const char *script) const {
|
int32_t LikelySubtags::getLikelyIndex(const char *language, const char *script) const {
|
||||||
if (uprv_strcmp(language, "und") == 0) {
|
if (uprv_strcmp(language, "und") == 0) {
|
||||||
language = "";
|
language = "";
|
||||||
}
|
}
|
||||||
|
@ -781,7 +856,7 @@ int32_t XLikelySubtags::getLikelyIndex(const char *language, const char *script)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t XLikelySubtags::trieNext(BytesTrie &iter, const char *s, int32_t i) {
|
int32_t LikelySubtags::trieNext(BytesTrie &iter, const char *s, int32_t i) {
|
||||||
UStringTrieResult result;
|
UStringTrieResult result;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
if ((c = s[i]) == 0) {
|
if ((c = s[i]) == 0) {
|
||||||
|
@ -814,7 +889,7 @@ int32_t XLikelySubtags::trieNext(BytesTrie &iter, const char *s, int32_t i) {
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int32_t XLikelySubtags::trieNext(BytesTrie &iter, StringPiece s, int32_t i) {
|
int32_t LikelySubtags::trieNext(BytesTrie &iter, StringPiece s, int32_t i) {
|
||||||
UStringTrieResult result;
|
UStringTrieResult result;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
if (s.length() == i) {
|
if (s.length() == i) {
|
||||||
|
@ -848,14 +923,13 @@ int32_t XLikelySubtags::trieNext(BytesTrie &iter, StringPiece s, int32_t i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LSR XLikelySubtags::minimizeSubtags(StringPiece language, StringPiece script,
|
LSR LikelySubtags::minimizeSubtags(StringPiece language, StringPiece script,
|
||||||
StringPiece region,
|
StringPiece region,
|
||||||
bool favorScript,
|
bool favorScript,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
LSR max = maximize(language, script, region, true, errorCode);
|
LSR max = maximize(language, script, region, true, errorCode);
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return max;
|
|
||||||
}
|
|
||||||
// If no match, return it.
|
// If no match, return it.
|
||||||
if (uprv_strlen(max.language) == 0 &&
|
if (uprv_strlen(max.language) == 0 &&
|
||||||
uprv_strlen(max.script) == 0 &&
|
uprv_strlen(max.script) == 0 &&
|
||||||
|
@ -868,9 +942,7 @@ LSR XLikelySubtags::minimizeSubtags(StringPiece language, StringPiece script,
|
||||||
}
|
}
|
||||||
// try language
|
// try language
|
||||||
LSR test = maximize(max.language, "", "", true, errorCode);
|
LSR test = maximize(max.language, "", "", true, errorCode);
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return max;
|
|
||||||
}
|
|
||||||
if (test.isEquivalentTo(max)) {
|
if (test.isEquivalentTo(max)) {
|
||||||
return LSR(max.language, "", "", LSR::DONT_CARE_FLAGS, errorCode);
|
return LSR(max.language, "", "", LSR::DONT_CARE_FLAGS, errorCode);
|
||||||
}
|
}
|
||||||
|
@ -879,27 +951,21 @@ LSR XLikelySubtags::minimizeSubtags(StringPiece language, StringPiece script,
|
||||||
// favor Region
|
// favor Region
|
||||||
// try language and region
|
// try language and region
|
||||||
test = maximize(max.language, "", max.region, true, errorCode);
|
test = maximize(max.language, "", max.region, true, errorCode);
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return max;
|
|
||||||
}
|
|
||||||
if (test.isEquivalentTo(max)) {
|
if (test.isEquivalentTo(max)) {
|
||||||
return LSR(max.language, "", max.region, LSR::DONT_CARE_FLAGS, errorCode);
|
return LSR(max.language, "", max.region, LSR::DONT_CARE_FLAGS, errorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try language and script
|
// try language and script
|
||||||
test = maximize(max.language, max.script, "", true, errorCode);
|
test = maximize(max.language, max.script, "", true, errorCode);
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return max;
|
|
||||||
}
|
|
||||||
if (test.isEquivalentTo(max)) {
|
if (test.isEquivalentTo(max)) {
|
||||||
return LSR(max.language, max.script, "", LSR::DONT_CARE_FLAGS, errorCode);
|
return LSR(max.language, max.script, "", LSR::DONT_CARE_FLAGS, errorCode);
|
||||||
}
|
}
|
||||||
if (favorScript) {
|
if (favorScript) {
|
||||||
// try language and region
|
// try language and region
|
||||||
test = maximize(max.language, "", max.region, true, errorCode);
|
test = maximize(max.language, "", max.region, true, errorCode);
|
||||||
if (U_FAILURE(errorCode)) {
|
if (U_FAILURE(errorCode)) { return {}; }
|
||||||
return max;
|
|
||||||
}
|
|
||||||
if (test.isEquivalentTo(max)) {
|
if (test.isEquivalentTo(max)) {
|
||||||
return LSR(max.language, "", max.region, LSR::DONT_CARE_FLAGS, errorCode);
|
return LSR(max.language, "", max.region, LSR::DONT_CARE_FLAGS, errorCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct XLikelySubtagsData;
|
struct LikelySubtagsData;
|
||||||
|
|
||||||
struct LocaleDistanceData {
|
struct LocaleDistanceData {
|
||||||
LocaleDistanceData() = default;
|
LocaleDistanceData() = default;
|
||||||
|
@ -37,15 +37,14 @@ private:
|
||||||
LocaleDistanceData &operator=(const LocaleDistanceData &) = delete;
|
LocaleDistanceData &operator=(const LocaleDistanceData &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(ICU-20777): Rename to just LikelySubtags.
|
class LikelySubtags final : public UMemory {
|
||||||
class XLikelySubtags final : public UMemory {
|
|
||||||
public:
|
public:
|
||||||
~XLikelySubtags();
|
~LikelySubtags();
|
||||||
|
|
||||||
static constexpr int32_t SKIP_SCRIPT = 1;
|
static constexpr int32_t SKIP_SCRIPT = 1;
|
||||||
|
|
||||||
// VisibleForTesting
|
// VisibleForTesting
|
||||||
static const XLikelySubtags *getSingleton(UErrorCode &errorCode);
|
static const LikelySubtags *getSingleton(UErrorCode &errorCode);
|
||||||
|
|
||||||
// VisibleForTesting
|
// VisibleForTesting
|
||||||
LSR makeMaximizedLsrFrom(const Locale &locale,
|
LSR makeMaximizedLsrFrom(const Locale &locale,
|
||||||
|
@ -72,9 +71,9 @@ public:
|
||||||
const LocaleDistanceData &getDistanceData() const { return distanceData; }
|
const LocaleDistanceData &getDistanceData() const { return distanceData; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XLikelySubtags(XLikelySubtagsData &data);
|
LikelySubtags(LikelySubtagsData &data);
|
||||||
XLikelySubtags(const XLikelySubtags &other) = delete;
|
LikelySubtags(const LikelySubtags &other) = delete;
|
||||||
XLikelySubtags &operator=(const XLikelySubtags &other) = delete;
|
LikelySubtags &operator=(const LikelySubtags &other) = delete;
|
||||||
|
|
||||||
static void initLikelySubtags(UErrorCode &errorCode);
|
static void initLikelySubtags(UErrorCode &errorCode);
|
||||||
|
|
||||||
|
@ -120,7 +119,7 @@ private:
|
||||||
int32_t lsrsLength;
|
int32_t lsrsLength;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// distance/matcher data: see comment in XLikelySubtagsData::load()
|
// distance/matcher data: see comment in LikelySubtagsData::load()
|
||||||
LocaleDistanceData distanceData;
|
LocaleDistanceData distanceData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "locmap.h"
|
#include "locmap.h"
|
||||||
#include "bytesinkutil.h"
|
|
||||||
#include "charstr.h"
|
#include "charstr.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
#include "cmemory.h"
|
#include "cmemory.h"
|
||||||
|
@ -49,6 +48,8 @@
|
||||||
* [MS-LCID] Windows Language Code Identifier (LCID) Reference
|
* [MS-LCID] Windows Language Code Identifier (LCID) Reference
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -87,7 +88,7 @@ typedef struct ILcidPosixMap
|
||||||
* @param posixID posix ID of the language_TERRITORY such as 'de_CH'
|
* @param posixID posix ID of the language_TERRITORY such as 'de_CH'
|
||||||
*/
|
*/
|
||||||
#define ILCID_POSIX_ELEMENT_ARRAY(hostID, languageID, posixID) \
|
#define ILCID_POSIX_ELEMENT_ARRAY(hostID, languageID, posixID) \
|
||||||
static const ILcidPosixElement locmap_ ## languageID [] = { \
|
constexpr ILcidPosixElement locmap_ ## languageID [] = { \
|
||||||
{LANGUAGE_LCID(hostID), #languageID}, /* parent locale */ \
|
{LANGUAGE_LCID(hostID), #languageID}, /* parent locale */ \
|
||||||
{hostID, #posixID}, \
|
{hostID, #posixID}, \
|
||||||
};
|
};
|
||||||
|
@ -97,7 +98,7 @@ static const ILcidPosixElement locmap_ ## languageID [] = { \
|
||||||
* @param id the POSIX ID, either a language or language_TERRITORY
|
* @param id the POSIX ID, either a language or language_TERRITORY
|
||||||
*/
|
*/
|
||||||
#define ILCID_POSIX_SUBTABLE(id) \
|
#define ILCID_POSIX_SUBTABLE(id) \
|
||||||
static const ILcidPosixElement locmap_ ## id [] =
|
constexpr ILcidPosixElement locmap_ ## id [] =
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -796,7 +797,7 @@ ILCID_POSIX_SUBTABLE(zh) {
|
||||||
ILCID_POSIX_ELEMENT_ARRAY(0x0435, zu, zu_ZA)
|
ILCID_POSIX_ELEMENT_ARRAY(0x0435, zu, zu_ZA)
|
||||||
|
|
||||||
/* This must be static and grouped by LCID. */
|
/* This must be static and grouped by LCID. */
|
||||||
static const ILcidPosixMap gPosixIDmap[] = {
|
constexpr ILcidPosixMap gPosixIDmap[] = {
|
||||||
ILCID_POSIX_MAP(af), /* af Afrikaans 0x36 */
|
ILCID_POSIX_MAP(af), /* af Afrikaans 0x36 */
|
||||||
ILCID_POSIX_MAP(am), /* am Amharic 0x5e */
|
ILCID_POSIX_MAP(am), /* am Amharic 0x5e */
|
||||||
ILCID_POSIX_MAP(ar), /* ar Arabic 0x01 */
|
ILCID_POSIX_MAP(ar), /* ar Arabic 0x01 */
|
||||||
|
@ -945,14 +946,14 @@ static const ILcidPosixMap gPosixIDmap[] = {
|
||||||
ILCID_POSIX_MAP(zu), /* zu Zulu 0x35 */
|
ILCID_POSIX_MAP(zu), /* zu Zulu 0x35 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t gLocaleCount = UPRV_LENGTHOF(gPosixIDmap);
|
constexpr uint32_t gLocaleCount = UPRV_LENGTHOF(gPosixIDmap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not call this function. It is called by hostID.
|
* Do not call this function. It is called by hostID.
|
||||||
* The function is not private because this struct must stay as a C struct,
|
* The function is not private because this struct must stay as a C struct,
|
||||||
* and this is an internal class.
|
* and this is an internal class.
|
||||||
*/
|
*/
|
||||||
static int32_t
|
int32_t
|
||||||
idCmp(const char* id1, const char* id2)
|
idCmp(const char* id1, const char* id2)
|
||||||
{
|
{
|
||||||
int32_t diffIdx = 0;
|
int32_t diffIdx = 0;
|
||||||
|
@ -972,9 +973,10 @@ idCmp(const char* id1, const char* id2)
|
||||||
* no equivalent Windows LCID.
|
* no equivalent Windows LCID.
|
||||||
* @return the LCID
|
* @return the LCID
|
||||||
*/
|
*/
|
||||||
static uint32_t
|
uint32_t
|
||||||
getHostID(const ILcidPosixMap *this_0, const char* posixID, UErrorCode* status)
|
getHostID(const ILcidPosixMap *this_0, const char* posixID, UErrorCode& status)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return locmap_root->hostID; }
|
||||||
int32_t bestIdx = 0;
|
int32_t bestIdx = 0;
|
||||||
int32_t bestIdxDiff = 0;
|
int32_t bestIdxDiff = 0;
|
||||||
int32_t posixIDlen = (int32_t)uprv_strlen(posixID);
|
int32_t posixIDlen = (int32_t)uprv_strlen(posixID);
|
||||||
|
@ -996,16 +998,16 @@ getHostID(const ILcidPosixMap *this_0, const char* posixID, UErrorCode* status)
|
||||||
if ((posixID[bestIdxDiff] == '_' || posixID[bestIdxDiff] == '@')
|
if ((posixID[bestIdxDiff] == '_' || posixID[bestIdxDiff] == '@')
|
||||||
&& this_0->regionMaps[bestIdx].posixID[bestIdxDiff] == 0)
|
&& this_0->regionMaps[bestIdx].posixID[bestIdxDiff] == 0)
|
||||||
{
|
{
|
||||||
*status = U_USING_FALLBACK_WARNING;
|
status = U_USING_FALLBACK_WARNING;
|
||||||
return this_0->regionMaps[bestIdx].hostID;
|
return this_0->regionMaps[bestIdx].hostID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*no match found */
|
/*no match found */
|
||||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return this_0->regionMaps->hostID;
|
return locmap_root->hostID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char*
|
const char*
|
||||||
getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
|
getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -1035,19 +1037,21 @@ getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
|
||||||
* quz -> qu
|
* quz -> qu
|
||||||
* prs -> fa
|
* prs -> fa
|
||||||
*/
|
*/
|
||||||
#define FIX_LANGUAGE_ID_TAG(buffer, len) \
|
void FIX_LANGUAGE_ID_TAG(char* buffer, int32_t len) {
|
||||||
if (len >= 3) { \
|
if (len >= 3) {
|
||||||
if (buffer[0] == 'q' && buffer[1] == 'u' && buffer[2] == 'z') {\
|
if (buffer[0] == 'q' && buffer[1] == 'u' && buffer[2] == 'z') {
|
||||||
buffer[2] = 0; \
|
buffer[2] = 0;
|
||||||
uprv_strcat(buffer, buffer+3); \
|
uprv_strcat(buffer, buffer+3);
|
||||||
} else if (buffer[0] == 'p' && buffer[1] == 'r' && buffer[2] == 's') {\
|
} else if (buffer[0] == 'p' && buffer[1] == 'r' && buffer[2] == 's') {
|
||||||
buffer[0] = 'f'; buffer[1] = 'a'; buffer[2] = 0; \
|
buffer[0] = 'f'; buffer[1] = 'a'; buffer[2] = 0;
|
||||||
uprv_strcat(buffer, buffer+3); \
|
uprv_strcat(buffer, buffer+3);
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
U_CAPI int32_t
|
U_CAPI int32_t
|
||||||
uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UErrorCode* status)
|
uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UErrorCode* status)
|
||||||
{
|
{
|
||||||
|
@ -1147,7 +1151,7 @@ uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UEr
|
||||||
|
|
||||||
/* no match found */
|
/* no match found */
|
||||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1176,11 +1180,7 @@ uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status)
|
||||||
// Check any for keywords.
|
// Check any for keywords.
|
||||||
if (uprv_strchr(localeID, '@'))
|
if (uprv_strchr(localeID, '@'))
|
||||||
{
|
{
|
||||||
icu::CharString collVal;
|
icu::CharString collVal = ulocimp_getKeywordValue(localeID, "collation", *status);
|
||||||
{
|
|
||||||
icu::CharStringByteSink sink(&collVal);
|
|
||||||
ulocimp_getKeywordValue(localeID, "collation", sink, status);
|
|
||||||
}
|
|
||||||
if (U_SUCCESS(*status) && !collVal.isEmpty())
|
if (U_SUCCESS(*status) && !collVal.isEmpty())
|
||||||
{
|
{
|
||||||
// If it contains the keyword collation, return 0 so that the LCID lookup table will be used.
|
// If it contains the keyword collation, return 0 so that the LCID lookup table will be used.
|
||||||
|
@ -1189,10 +1189,7 @@ uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the locale ID contains keywords other than collation, just use the base name.
|
// If the locale ID contains keywords other than collation, just use the base name.
|
||||||
{
|
baseName = ulocimp_getBaseName(localeID, *status);
|
||||||
icu::CharStringByteSink sink(&baseName);
|
|
||||||
ulocimp_getBaseName(localeID, sink, status);
|
|
||||||
}
|
|
||||||
if (U_SUCCESS(*status) && !baseName.isEmpty())
|
if (U_SUCCESS(*status) && !baseName.isEmpty())
|
||||||
{
|
{
|
||||||
mylocaleID = baseName.data();
|
mylocaleID = baseName.data();
|
||||||
|
@ -1201,11 +1198,7 @@ uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will change it from de_DE@collation=phonebook to de-DE-u-co-phonebk form
|
// this will change it from de_DE@collation=phonebook to de-DE-u-co-phonebk form
|
||||||
icu::CharString asciiBCP47Tag;
|
icu::CharString asciiBCP47Tag = ulocimp_toLanguageTag(mylocaleID, false, *status);
|
||||||
{
|
|
||||||
icu::CharStringByteSink sink(&asciiBCP47Tag);
|
|
||||||
ulocimp_toLanguageTag(mylocaleID, sink, false, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (U_SUCCESS(*status))
|
if (U_SUCCESS(*status))
|
||||||
{
|
{
|
||||||
|
@ -1253,6 +1246,14 @@ uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status)
|
||||||
U_CAPI uint32_t
|
U_CAPI uint32_t
|
||||||
uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
|
uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(*status) ||
|
||||||
|
langID == nullptr ||
|
||||||
|
posixID == nullptr ||
|
||||||
|
uprv_strlen(langID) < 2 ||
|
||||||
|
uprv_strlen(posixID) < 2) {
|
||||||
|
return locmap_root->hostID;
|
||||||
|
}
|
||||||
|
|
||||||
// This function does the table lookup when native platform name->lcid conversion isn't available,
|
// This function does the table lookup when native platform name->lcid conversion isn't available,
|
||||||
// or for locales that don't follow patterns the platform expects.
|
// or for locales that don't follow patterns the platform expects.
|
||||||
uint32_t low = 0;
|
uint32_t low = 0;
|
||||||
|
@ -1266,11 +1267,6 @@ uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
|
||||||
UErrorCode myStatus;
|
UErrorCode myStatus;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
|
||||||
/* Check for incomplete id. */
|
|
||||||
if (!langID || !posixID || uprv_strlen(langID) < 2 || uprv_strlen(posixID) < 2) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Binary search for the map entry for normal cases */
|
/*Binary search for the map entry for normal cases */
|
||||||
|
|
||||||
while (high > low) /*binary search*/{
|
while (high > low) /*binary search*/{
|
||||||
|
@ -1288,7 +1284,7 @@ uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
|
||||||
low = mid;
|
low = mid;
|
||||||
}
|
}
|
||||||
else /*we found it*/{
|
else /*we found it*/{
|
||||||
return getHostID(&gPosixIDmap[mid], posixID, status);
|
return getHostID(&gPosixIDmap[mid], posixID, *status);
|
||||||
}
|
}
|
||||||
oldmid = mid;
|
oldmid = mid;
|
||||||
}
|
}
|
||||||
|
@ -1299,7 +1295,7 @@ uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
|
||||||
*/
|
*/
|
||||||
for (idx = 0; idx < gLocaleCount; idx++ ) {
|
for (idx = 0; idx < gLocaleCount; idx++ ) {
|
||||||
myStatus = U_ZERO_ERROR;
|
myStatus = U_ZERO_ERROR;
|
||||||
value = getHostID(&gPosixIDmap[idx], posixID, &myStatus);
|
value = getHostID(&gPosixIDmap[idx], posixID, myStatus);
|
||||||
if (myStatus == U_ZERO_ERROR) {
|
if (myStatus == U_ZERO_ERROR) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -1315,5 +1311,5 @@ uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
|
||||||
|
|
||||||
/* no match found */
|
/* no match found */
|
||||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0; /* return international (root) */
|
return locmap_root->hostID; /* return international (root) */
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "unicode/putil.h"
|
#include "unicode/putil.h"
|
||||||
#include "unicode/uloc.h"
|
#include "unicode/uloc.h"
|
||||||
#include "unicode/ures.h"
|
#include "unicode/ures.h"
|
||||||
#include "bytesinkutil.h"
|
|
||||||
#include "charstr.h"
|
#include "charstr.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
#include "ulocimp.h"
|
#include "ulocimp.h"
|
||||||
|
@ -50,10 +49,10 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
||||||
int32_t *pLength,
|
int32_t *pLength,
|
||||||
UErrorCode *pErrorCode)
|
UErrorCode *pErrorCode)
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(*pErrorCode)) { return nullptr; }
|
||||||
/* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
|
/* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
|
||||||
const char16_t *item=nullptr;
|
const char16_t *item=nullptr;
|
||||||
UErrorCode errorCode;
|
UErrorCode errorCode;
|
||||||
char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open the bundle for the current locale
|
* open the bundle for the current locale
|
||||||
|
@ -129,14 +128,15 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u_UCharsToChars(fallbackLocale, explicitFallbackName, len);
|
icu::CharString explicitFallbackName;
|
||||||
|
explicitFallbackName.appendInvariantChars(fallbackLocale, len, errorCode);
|
||||||
|
|
||||||
/* guard against recursive fallback */
|
/* guard against recursive fallback */
|
||||||
if(uprv_strcmp(explicitFallbackName, locale)==0){
|
if (explicitFallbackName == locale) {
|
||||||
*pErrorCode = U_INTERNAL_PROGRAM_ERROR;
|
*pErrorCode = U_INTERNAL_PROGRAM_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rb.adoptInstead(ures_open(path, explicitFallbackName, &errorCode));
|
rb.adoptInstead(ures_open(path, explicitFallbackName.data(), &errorCode));
|
||||||
if(U_FAILURE(errorCode)){
|
if(U_FAILURE(errorCode)){
|
||||||
*pErrorCode = errorCode;
|
*pErrorCode = errorCode;
|
||||||
break;
|
break;
|
||||||
|
@ -150,21 +150,21 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULayoutType
|
namespace {
|
||||||
|
|
||||||
|
ULayoutType
|
||||||
_uloc_getOrientationHelper(const char* localeId,
|
_uloc_getOrientationHelper(const char* localeId,
|
||||||
const char* key,
|
const char* key,
|
||||||
UErrorCode *status)
|
UErrorCode& status)
|
||||||
{
|
{
|
||||||
ULayoutType result = ULOC_LAYOUT_UNKNOWN;
|
ULayoutType result = ULOC_LAYOUT_UNKNOWN;
|
||||||
|
|
||||||
if (!U_FAILURE(*status)) {
|
if (U_FAILURE(status)) { return result; }
|
||||||
icu::CharString localeBuffer;
|
|
||||||
{
|
icu::CharString localeBuffer = ulocimp_canonicalize(localeId, status);
|
||||||
icu::CharStringByteSink sink(&localeBuffer);
|
|
||||||
ulocimp_canonicalize(localeId, sink, status);
|
if (U_FAILURE(status)) { return result; }
|
||||||
}
|
|
||||||
|
|
||||||
if (!U_FAILURE(*status)) {
|
|
||||||
int32_t length = 0;
|
int32_t length = 0;
|
||||||
const char16_t* const value =
|
const char16_t* const value =
|
||||||
uloc_getTableStringWithFallback(
|
uloc_getTableStringWithFallback(
|
||||||
|
@ -174,9 +174,11 @@ _uloc_getOrientationHelper(const char* localeId,
|
||||||
nullptr,
|
nullptr,
|
||||||
key,
|
key,
|
||||||
&length,
|
&length,
|
||||||
status);
|
&status);
|
||||||
|
|
||||||
if (!U_FAILURE(*status) && length != 0) {
|
if (U_FAILURE(status)) { return result; }
|
||||||
|
|
||||||
|
if (length != 0) {
|
||||||
switch(value[0])
|
switch(value[0])
|
||||||
{
|
{
|
||||||
case 0x0062: /* 'b' */
|
case 0x0062: /* 'b' */
|
||||||
|
@ -192,21 +194,21 @@ _uloc_getOrientationHelper(const char* localeId,
|
||||||
result = ULOC_LAYOUT_TTB;
|
result = ULOC_LAYOUT_TTB;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
status = U_INTERNAL_PROGRAM_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
U_CAPI ULayoutType U_EXPORT2
|
U_CAPI ULayoutType U_EXPORT2
|
||||||
uloc_getCharacterOrientation(const char* localeId,
|
uloc_getCharacterOrientation(const char* localeId,
|
||||||
UErrorCode *status)
|
UErrorCode *status)
|
||||||
{
|
{
|
||||||
return _uloc_getOrientationHelper(localeId, "characters", status);
|
return _uloc_getOrientationHelper(localeId, "characters", *status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -220,5 +222,5 @@ U_CAPI ULayoutType U_EXPORT2
|
||||||
uloc_getLineOrientation(const char* localeId,
|
uloc_getLineOrientation(const char* localeId,
|
||||||
UErrorCode *status)
|
UErrorCode *status)
|
||||||
{
|
{
|
||||||
return _uloc_getOrientationHelper(localeId, "lines", status);
|
return _uloc_getOrientationHelper(localeId, "lines", *status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,9 +145,7 @@ LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& res
|
||||||
Locale&
|
Locale&
|
||||||
LocaleUtility::initLocaleFromName(const UnicodeString& id, Locale& result)
|
LocaleUtility::initLocaleFromName(const UnicodeString& id, Locale& result)
|
||||||
{
|
{
|
||||||
enum { BUFLEN = 128 }; // larger than ever needed
|
if (id.isBogus()) {
|
||||||
|
|
||||||
if (id.isBogus() || id.length() >= BUFLEN) {
|
|
||||||
result.setToBogus();
|
result.setToBogus();
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -168,24 +166,29 @@ LocaleUtility::initLocaleFromName(const UnicodeString& id, Locale& result)
|
||||||
*
|
*
|
||||||
* There should be only at most one '@' in a locale ID.
|
* There should be only at most one '@' in a locale ID.
|
||||||
*/
|
*/
|
||||||
char buffer[BUFLEN];
|
CharString buffer;
|
||||||
int32_t prev, i;
|
int32_t prev, i;
|
||||||
prev = 0;
|
prev = 0;
|
||||||
for(;;) {
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
do {
|
||||||
i = id.indexOf((char16_t)0x40, prev);
|
i = id.indexOf((char16_t)0x40, prev);
|
||||||
if(i < 0) {
|
if(i < 0) {
|
||||||
// no @ between prev and the rest of the string
|
// no @ between prev and the rest of the string
|
||||||
id.extract(prev, INT32_MAX, buffer + prev, BUFLEN - prev, US_INV);
|
buffer.appendInvariantChars(id.tempSubString(prev), status);
|
||||||
break; // done
|
break; // done
|
||||||
} else {
|
} else {
|
||||||
// normal invariant-character conversion for text between @s
|
// normal invariant-character conversion for text between @s
|
||||||
id.extract(prev, i - prev, buffer + prev, BUFLEN - prev, US_INV);
|
buffer.appendInvariantChars(id.tempSubString(prev, i - prev), status);
|
||||||
// manually "convert" U+0040 at id[i] into '@' at buffer[i]
|
// manually "convert" U+0040 at id[i] into '@' at buffer[i]
|
||||||
buffer[i] = '@';
|
buffer.append('@', status);
|
||||||
prev = i + 1;
|
prev = i + 1;
|
||||||
}
|
}
|
||||||
|
} while (U_SUCCESS(status));
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
result.setToBogus();
|
||||||
|
} else {
|
||||||
|
result = Locale::createFromName(buffer.data());
|
||||||
}
|
}
|
||||||
result = Locale::createFromName(buffer);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +262,7 @@ LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
|
||||||
return htp;
|
return htp;
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool
|
bool
|
||||||
LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& child)
|
LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& child)
|
||||||
{
|
{
|
||||||
return child.indexOf(root) == 0 &&
|
return child.indexOf(root) == 0 &&
|
||||||
|
@ -271,5 +274,3 @@ U_NAMESPACE_END
|
||||||
|
|
||||||
/* !UCONFIG_NO_SERVICE */
|
/* !UCONFIG_NO_SERVICE */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
static Locale& initLocaleFromName(const UnicodeString& id, Locale& result);
|
static Locale& initLocaleFromName(const UnicodeString& id, Locale& result);
|
||||||
static UnicodeString& initNameFromLocale(const Locale& locale, UnicodeString& result);
|
static UnicodeString& initNameFromLocale(const Locale& locale, UnicodeString& result);
|
||||||
static const Hashtable* getAvailableLocaleNames(const UnicodeString& bundleID);
|
static const Hashtable* getAvailableLocaleNames(const UnicodeString& bundleID);
|
||||||
static UBool isFallbackOf(const UnicodeString& root, const UnicodeString& child);
|
static bool isFallbackOf(const UnicodeString& root, const UnicodeString& child);
|
||||||
};
|
};
|
||||||
|
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
|
|
@ -999,7 +999,6 @@ MessagePattern::parseDouble(int32_t start, int32_t limit, UBool allowInfinity,
|
||||||
}
|
}
|
||||||
setParseError(parseError, start /*, limit*/); // Bad syntax for numeric value.
|
setParseError(parseError, start /*, limit*/); // Bad syntax for numeric value.
|
||||||
errorCode=U_PATTERN_SYNTAX_ERROR;
|
errorCode=U_PATTERN_SYNTAX_ERROR;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
|
|
|
@ -1390,8 +1390,11 @@ Normalizer2Impl::composePair(UChar32 a, UChar32 b) const {
|
||||||
} else if(norm16<minYesNoMappingsOnly) {
|
} else if(norm16<minYesNoMappingsOnly) {
|
||||||
// a combines forward.
|
// a combines forward.
|
||||||
if(isJamoL(norm16)) {
|
if(isJamoL(norm16)) {
|
||||||
|
if (b < Hangul::JAMO_V_BASE) {
|
||||||
|
return U_SENTINEL;
|
||||||
|
}
|
||||||
b-=Hangul::JAMO_V_BASE;
|
b-=Hangul::JAMO_V_BASE;
|
||||||
if(0<=b && b<Hangul::JAMO_V_COUNT) {
|
if(b<Hangul::JAMO_V_COUNT) {
|
||||||
return
|
return
|
||||||
(Hangul::HANGUL_BASE+
|
(Hangul::HANGUL_BASE+
|
||||||
((a-Hangul::JAMO_L_BASE)*Hangul::JAMO_V_COUNT+b)*
|
((a-Hangul::JAMO_L_BASE)*Hangul::JAMO_V_COUNT+b)*
|
||||||
|
@ -1400,8 +1403,11 @@ Normalizer2Impl::composePair(UChar32 a, UChar32 b) const {
|
||||||
return U_SENTINEL;
|
return U_SENTINEL;
|
||||||
}
|
}
|
||||||
} else if(isHangulLV(norm16)) {
|
} else if(isHangulLV(norm16)) {
|
||||||
|
if (b <= Hangul::JAMO_T_BASE) {
|
||||||
|
return U_SENTINEL;
|
||||||
|
}
|
||||||
b-=Hangul::JAMO_T_BASE;
|
b-=Hangul::JAMO_T_BASE;
|
||||||
if(0<b && b<Hangul::JAMO_T_COUNT) { // not b==0!
|
if(b<Hangul::JAMO_T_COUNT) { // not b==0!
|
||||||
return a+b;
|
return a+b;
|
||||||
} else {
|
} else {
|
||||||
return U_SENTINEL;
|
return U_SENTINEL;
|
||||||
|
|
|
@ -141,12 +141,12 @@ public:
|
||||||
/** Constructs only; init() should be called. */
|
/** Constructs only; init() should be called. */
|
||||||
ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest) :
|
ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest) :
|
||||||
impl(ni), str(dest),
|
impl(ni), str(dest),
|
||||||
start(NULL), reorderStart(NULL), limit(NULL),
|
start(nullptr), reorderStart(nullptr), limit(nullptr),
|
||||||
remainingCapacity(0), lastCC(0) {}
|
remainingCapacity(0), lastCC(0) {}
|
||||||
/** Constructs, removes the string contents, and initializes for a small initial capacity. */
|
/** Constructs, removes the string contents, and initializes for a small initial capacity. */
|
||||||
ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest, UErrorCode &errorCode);
|
ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest, UErrorCode &errorCode);
|
||||||
~ReorderingBuffer() {
|
~ReorderingBuffer() {
|
||||||
if(start!=NULL) {
|
if (start != nullptr) {
|
||||||
str.releaseBuffer((int32_t)(limit-start));
|
str.releaseBuffer((int32_t)(limit-start));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ private:
|
||||||
*/
|
*/
|
||||||
class U_COMMON_API Normalizer2Impl : public UObject {
|
class U_COMMON_API Normalizer2Impl : public UObject {
|
||||||
public:
|
public:
|
||||||
Normalizer2Impl() : normTrie(NULL), fCanonIterData(NULL) { }
|
Normalizer2Impl() : normTrie(nullptr), fCanonIterData(nullptr) {}
|
||||||
virtual ~Normalizer2Impl();
|
virtual ~Normalizer2Impl();
|
||||||
|
|
||||||
void init(const int32_t *inIndexes, const UCPTrie *inTrie,
|
void init(const int32_t *inIndexes, const UCPTrie *inTrie,
|
||||||
|
@ -623,7 +623,7 @@ private:
|
||||||
const uint16_t *getMapping(uint16_t norm16) const { return extraData+(norm16>>OFFSET_SHIFT); }
|
const uint16_t *getMapping(uint16_t norm16) const { return extraData+(norm16>>OFFSET_SHIFT); }
|
||||||
const uint16_t *getCompositionsListForDecompYes(uint16_t norm16) const {
|
const uint16_t *getCompositionsListForDecompYes(uint16_t norm16) const {
|
||||||
if(norm16<JAMO_L || MIN_NORMAL_MAYBE_YES<=norm16) {
|
if(norm16<JAMO_L || MIN_NORMAL_MAYBE_YES<=norm16) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
} else if(norm16<minMaybeYes) {
|
} else if(norm16<minMaybeYes) {
|
||||||
return getMapping(norm16); // for yesYes; if Jamo L: harmless empty list
|
return getMapping(norm16); // for yesYes; if Jamo L: harmless empty list
|
||||||
} else {
|
} else {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1498,7 +1498,6 @@ static void U_CALLCONV dataDirectoryInitFn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
u_setDataDirectory(path);
|
u_setDataDirectory(path);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI const char * U_EXPORT2
|
U_CAPI const char * U_EXPORT2
|
||||||
|
@ -1622,7 +1621,7 @@ static const char *uprv_getPOSIXIDForCategory(int category)
|
||||||
* of nullptr, will modify the libc behavior.
|
* of nullptr, will modify the libc behavior.
|
||||||
*/
|
*/
|
||||||
posixID = setlocale(category, nullptr);
|
posixID = setlocale(category, nullptr);
|
||||||
if ((posixID == 0)
|
if ((posixID == nullptr)
|
||||||
|| (uprv_strcmp("C", posixID) == 0)
|
|| (uprv_strcmp("C", posixID) == 0)
|
||||||
|| (uprv_strcmp("POSIX", posixID) == 0))
|
|| (uprv_strcmp("POSIX", posixID) == 0))
|
||||||
{
|
{
|
||||||
|
@ -1636,16 +1635,16 @@ static const char *uprv_getPOSIXIDForCategory(int category)
|
||||||
posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
|
posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
|
||||||
if ((posixID == 0) || (posixID[0] == '\0')) {
|
if ((posixID == 0) || (posixID[0] == '\0')) {
|
||||||
#else
|
#else
|
||||||
if (posixID == 0) {
|
if (posixID == nullptr) {
|
||||||
posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
|
posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
|
||||||
if (posixID == 0) {
|
if (posixID == nullptr) {
|
||||||
#endif
|
#endif
|
||||||
posixID = getenv("LANG");
|
posixID = getenv("LANG");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((posixID==0)
|
if ((posixID == nullptr)
|
||||||
|| (uprv_strcmp("C", posixID) == 0)
|
|| (uprv_strcmp("C", posixID) == 0)
|
||||||
|| (uprv_strcmp("POSIX", posixID) == 0))
|
|| (uprv_strcmp("POSIX", posixID) == 0))
|
||||||
{
|
{
|
||||||
|
@ -1665,7 +1664,7 @@ static const char *uprv_getPOSIXIDForCategory(int category)
|
||||||
static const char *uprv_getPOSIXIDForDefaultLocale()
|
static const char *uprv_getPOSIXIDForDefaultLocale()
|
||||||
{
|
{
|
||||||
static const char* posixID = nullptr;
|
static const char* posixID = nullptr;
|
||||||
if (posixID == 0) {
|
if (posixID == nullptr) {
|
||||||
posixID = uprv_getPOSIXIDForCategory(LC_MESSAGES);
|
posixID = uprv_getPOSIXIDForCategory(LC_MESSAGES);
|
||||||
}
|
}
|
||||||
return posixID;
|
return posixID;
|
||||||
|
|
|
@ -1212,7 +1212,7 @@ RuleBasedBreakIterator::getLanguageBreakEngine(UChar32 c, const char* locale) {
|
||||||
fLanguageBreakEngines = new UStack(status);
|
fLanguageBreakEngines = new UStack(status);
|
||||||
if (fLanguageBreakEngines == nullptr || U_FAILURE(status)) {
|
if (fLanguageBreakEngines == nullptr || U_FAILURE(status)) {
|
||||||
delete fLanguageBreakEngines;
|
delete fLanguageBreakEngines;
|
||||||
fLanguageBreakEngines = 0;
|
fLanguageBreakEngines = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1252,7 @@ RuleBasedBreakIterator::getLanguageBreakEngine(UChar32 c, const char* locale) {
|
||||||
U_ASSERT(!fLanguageBreakEngines->hasDeleter());
|
U_ASSERT(!fLanguageBreakEngines->hasDeleter());
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
delete fUnhandledBreakEngine;
|
delete fUnhandledBreakEngine;
|
||||||
fUnhandledBreakEngine = 0;
|
fUnhandledBreakEngine = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,6 @@ void RuleBasedBreakIterator::BreakCache::following(int32_t startPos, UErrorCode
|
||||||
fBI->fDone = false;
|
fBI->fDone = false;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,7 +264,6 @@ void RuleBasedBreakIterator::BreakCache::preceding(int32_t startPos, UErrorCode
|
||||||
current();
|
current();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,7 +275,6 @@ void RuleBasedBreakIterator::BreakCache::nextOL() {
|
||||||
fBI->fDone = !populateFollowing();
|
fBI->fDone = !populateFollowing();
|
||||||
fBI->fPosition = fTextIdx;
|
fBI->fPosition = fTextIdx;
|
||||||
fBI->fRuleStatusIndex = fStatuses[fBufIdx];
|
fBI->fRuleStatusIndex = fStatuses[fBufIdx];
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -297,7 +294,6 @@ void RuleBasedBreakIterator::BreakCache::previous(UErrorCode &status) {
|
||||||
fBI->fDone = (fBufIdx == initialBufIdx);
|
fBI->fDone = (fBufIdx == initialBufIdx);
|
||||||
fBI->fPosition = fTextIdx;
|
fBI->fPosition = fTextIdx;
|
||||||
fBI->fRuleStatusIndex = fStatuses[fBufIdx];
|
fBI->fRuleStatusIndex = fStatuses[fBufIdx];
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -123,19 +123,66 @@ RBBINode::~RBBINode() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
delete fLeftChild;
|
// Avoid using a recursive implementation because of stack overflow problems.
|
||||||
|
// See bug ICU-22584.
|
||||||
|
// delete fLeftChild;
|
||||||
|
NRDeleteNode(fLeftChild);
|
||||||
fLeftChild = nullptr;
|
fLeftChild = nullptr;
|
||||||
delete fRightChild;
|
// delete fRightChild;
|
||||||
|
NRDeleteNode(fRightChild);
|
||||||
fRightChild = nullptr;
|
fRightChild = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delete fFirstPosSet;
|
delete fFirstPosSet;
|
||||||
delete fLastPosSet;
|
delete fLastPosSet;
|
||||||
delete fFollowPos;
|
delete fFollowPos;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-recursive delete of a node + its children. Used from the node destructor
|
||||||
|
* instead of the more obvious recursive implementation to avoid problems with
|
||||||
|
* stack overflow with some perverse test rule data (from fuzzing).
|
||||||
|
*/
|
||||||
|
void RBBINode::NRDeleteNode(RBBINode *node) {
|
||||||
|
if (node == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RBBINode *stopNode = node->fParent;
|
||||||
|
RBBINode *nextNode = node;
|
||||||
|
while (nextNode != stopNode && nextNode != nullptr) {
|
||||||
|
RBBINode *currentNode = nextNode;
|
||||||
|
|
||||||
|
if ((currentNode->fLeftChild == nullptr && currentNode->fRightChild == nullptr) ||
|
||||||
|
currentNode->fType == varRef || // varRef and setRef nodes do not
|
||||||
|
currentNode->fType == setRef) { // own their children nodes.
|
||||||
|
// CurrentNode is effectively a leaf node; it's safe to go ahead and delete it.
|
||||||
|
nextNode = currentNode->fParent;
|
||||||
|
if (nextNode) {
|
||||||
|
if (nextNode->fLeftChild == currentNode) {
|
||||||
|
nextNode->fLeftChild = nullptr;
|
||||||
|
} else if (nextNode->fRightChild == currentNode) {
|
||||||
|
nextNode->fRightChild = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete currentNode;
|
||||||
|
} else if (currentNode->fLeftChild) {
|
||||||
|
nextNode = currentNode->fLeftChild;
|
||||||
|
if (nextNode->fParent == nullptr) {
|
||||||
|
nextNode->fParent = currentNode;
|
||||||
|
// fParent isn't always set; do it now if not.
|
||||||
|
}
|
||||||
|
U_ASSERT(nextNode->fParent == currentNode);
|
||||||
|
} else if (currentNode->fRightChild) {
|
||||||
|
nextNode = currentNode->fRightChild;
|
||||||
|
if (nextNode->fParent == nullptr) {
|
||||||
|
nextNode->fParent = currentNode;
|
||||||
|
// fParent isn't always set; do it now if not.
|
||||||
|
}
|
||||||
|
U_ASSERT(nextNode->fParent == currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -192,7 +239,17 @@ RBBINode *RBBINode::cloneTree() {
|
||||||
// nested references are handled by cloneTree(), not here.
|
// nested references are handled by cloneTree(), not here.
|
||||||
//
|
//
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
RBBINode *RBBINode::flattenVariables() {
|
constexpr int kRecursiveDepthLimit = 3500;
|
||||||
|
RBBINode *RBBINode::flattenVariables(UErrorCode& status, int depth) {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
// If the depth of the stack is too deep, we return U_INPUT_TOO_LONG_ERROR
|
||||||
|
// to avoid stack overflow crash.
|
||||||
|
if (depth > kRecursiveDepthLimit) {
|
||||||
|
status = U_INPUT_TOO_LONG_ERROR;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
if (fType == varRef) {
|
if (fType == varRef) {
|
||||||
RBBINode *retNode = fLeftChild->cloneTree();
|
RBBINode *retNode = fLeftChild->cloneTree();
|
||||||
if (retNode != nullptr) {
|
if (retNode != nullptr) {
|
||||||
|
@ -204,11 +261,11 @@ RBBINode *RBBINode::flattenVariables() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fLeftChild != nullptr) {
|
if (fLeftChild != nullptr) {
|
||||||
fLeftChild = fLeftChild->flattenVariables();
|
fLeftChild = fLeftChild->flattenVariables(status, depth+1);
|
||||||
fLeftChild->fParent = this;
|
fLeftChild->fParent = this;
|
||||||
}
|
}
|
||||||
if (fRightChild != nullptr) {
|
if (fRightChild != nullptr) {
|
||||||
fRightChild = fRightChild->flattenVariables();
|
fRightChild = fRightChild->flattenVariables(status, depth+1);
|
||||||
fRightChild->fParent = this;
|
fRightChild->fParent = this;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -94,9 +94,10 @@ class RBBINode : public UMemory {
|
||||||
RBBINode(NodeType t);
|
RBBINode(NodeType t);
|
||||||
RBBINode(const RBBINode &other);
|
RBBINode(const RBBINode &other);
|
||||||
~RBBINode();
|
~RBBINode();
|
||||||
|
static void NRDeleteNode(RBBINode *node);
|
||||||
|
|
||||||
RBBINode *cloneTree();
|
RBBINode *cloneTree();
|
||||||
RBBINode *flattenVariables();
|
RBBINode *flattenVariables(UErrorCode &status, int depth=0);
|
||||||
void flattenSets();
|
void flattenSets();
|
||||||
void findNodes(UVector *dest, RBBINode::NodeType kind, UErrorCode &status);
|
void findNodes(UVector *dest, RBBINode::NodeType kind, UErrorCode &status);
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,8 @@ RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString &rules,
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(fSetBuilder == 0 || fScanner == 0 || fUSetNodes == 0 || fRuleStatusVals == 0) {
|
if (fSetBuilder == nullptr || fScanner == nullptr ||
|
||||||
|
fUSetNodes == nullptr || fRuleStatusVals == nullptr) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +157,7 @@ RBBIDataHeader *RBBIRuleBuilder::flattenData() {
|
||||||
int32_t statusTableSize = align8(fRuleStatusVals->size() * sizeof(int32_t));
|
int32_t statusTableSize = align8(fRuleStatusVals->size() * sizeof(int32_t));
|
||||||
|
|
||||||
int32_t rulesLengthInUTF8 = 0;
|
int32_t rulesLengthInUTF8 = 0;
|
||||||
u_strToUTF8WithSub(0, 0, &rulesLengthInUTF8,
|
u_strToUTF8WithSub(nullptr, 0, &rulesLengthInUTF8,
|
||||||
fStrippedRules.getBuffer(), fStrippedRules.length(),
|
fStrippedRules.getBuffer(), fStrippedRules.length(),
|
||||||
0xfffd, nullptr, fStatus);
|
0xfffd, nullptr, fStatus);
|
||||||
*fStatus = U_ZERO_ERROR;
|
*fStatus = U_ZERO_ERROR;
|
||||||
|
|
|
@ -289,6 +289,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
||||||
|
|
||||||
// Terminate expression, leaves expression parse tree rooted in TOS node.
|
// Terminate expression, leaves expression parse tree rooted in TOS node.
|
||||||
fixOpStack(RBBINode::precStart);
|
fixOpStack(RBBINode::precStart);
|
||||||
|
if (U_FAILURE(*fRB->fStatus)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
RBBINode *startExprNode = fNodeStack[fNodeStackPtr-2];
|
RBBINode *startExprNode = fNodeStack[fNodeStackPtr-2];
|
||||||
RBBINode *varRefNode = fNodeStack[fNodeStackPtr-1];
|
RBBINode *varRefNode = fNodeStack[fNodeStackPtr-1];
|
||||||
|
@ -312,6 +315,11 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
||||||
UErrorCode t = *fRB->fStatus;
|
UErrorCode t = *fRB->fStatus;
|
||||||
*fRB->fStatus = U_ZERO_ERROR;
|
*fRB->fStatus = U_ZERO_ERROR;
|
||||||
error(t);
|
error(t);
|
||||||
|
// When adding $variableRef to the symbol table fail, Delete
|
||||||
|
// both nodes because deleting varRefNode will not delete
|
||||||
|
// RHSExprNode internally.
|
||||||
|
delete RHSExprNode;
|
||||||
|
delete varRefNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up the stack.
|
// Clean up the stack.
|
||||||
|
@ -522,7 +530,13 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
||||||
n = fNodeStack[fNodeStackPtr];
|
n = fNodeStack[fNodeStackPtr];
|
||||||
uint32_t v = u_charDigitValue(fC.fChar);
|
uint32_t v = u_charDigitValue(fC.fChar);
|
||||||
U_ASSERT(v < 10);
|
U_ASSERT(v < 10);
|
||||||
n->fVal = n->fVal*10 + v;
|
int64_t updated = static_cast<int64_t>(n->fVal)*10 + v;
|
||||||
|
// Avoid overflow n->fVal
|
||||||
|
if (updated > INT32_MAX) {
|
||||||
|
error(U_BRK_RULE_SYNTAX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n->fVal = static_cast<int32_t>(updated);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,6 +776,7 @@ void RBBIRuleScanner::findSetFor(const UnicodeString &s, RBBINode *node, Unicode
|
||||||
RBBINode *usetNode = new RBBINode(RBBINode::uset);
|
RBBINode *usetNode = new RBBINode(RBBINode::uset);
|
||||||
if (usetNode == nullptr) {
|
if (usetNode == nullptr) {
|
||||||
error(U_MEMORY_ALLOCATION_ERROR);
|
error(U_MEMORY_ALLOCATION_ERROR);
|
||||||
|
delete setToAdopt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
usetNode->fInputSet = setToAdopt;
|
usetNode->fInputSet = setToAdopt;
|
||||||
|
@ -796,8 +811,6 @@ void RBBIRuleScanner::findSetFor(const UnicodeString &s, RBBINode *node, Unicode
|
||||||
el->key = tkey;
|
el->key = tkey;
|
||||||
el->val = usetNode;
|
el->val = usetNode;
|
||||||
uhash_put(fSetTable, el->key, el, fRB->fStatus);
|
uhash_put(fSetTable, el->key, el, fRB->fStatus);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -926,6 +939,9 @@ void RBBIRuleScanner::nextChar(RBBIRuleChar &c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c.fChar == (UChar32)-1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (fQuoteMode) {
|
if (fQuoteMode) {
|
||||||
c.fEscaped = true;
|
c.fEscaped = true;
|
||||||
}
|
}
|
||||||
|
@ -1199,7 +1215,6 @@ RBBINode *RBBIRuleScanner::pushNewNode(RBBINode::NodeType t) {
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void RBBIRuleScanner::scanSet() {
|
void RBBIRuleScanner::scanSet() {
|
||||||
UnicodeSet *uset;
|
|
||||||
ParsePosition pos;
|
ParsePosition pos;
|
||||||
int startPos;
|
int startPos;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1211,12 +1226,12 @@ void RBBIRuleScanner::scanSet() {
|
||||||
pos.setIndex(fScanIndex);
|
pos.setIndex(fScanIndex);
|
||||||
startPos = fScanIndex;
|
startPos = fScanIndex;
|
||||||
UErrorCode localStatus = U_ZERO_ERROR;
|
UErrorCode localStatus = U_ZERO_ERROR;
|
||||||
uset = new UnicodeSet();
|
LocalPointer<UnicodeSet> uset(new UnicodeSet(), localStatus);
|
||||||
if (uset == nullptr) {
|
if (U_FAILURE(localStatus)) {
|
||||||
localStatus = U_MEMORY_ALLOCATION_ERROR;
|
error(localStatus);
|
||||||
} else {
|
return;
|
||||||
uset->applyPatternIgnoreSpace(fRB->fRules, pos, fSymbolTable, localStatus);
|
|
||||||
}
|
}
|
||||||
|
uset->applyPatternIgnoreSpace(fRB->fRules, pos, fSymbolTable, localStatus);
|
||||||
if (U_FAILURE(localStatus)) {
|
if (U_FAILURE(localStatus)) {
|
||||||
// TODO: Get more accurate position of the error from UnicodeSet's return info.
|
// TODO: Get more accurate position of the error from UnicodeSet's return info.
|
||||||
// UnicodeSet appears to not be reporting correctly at this time.
|
// UnicodeSet appears to not be reporting correctly at this time.
|
||||||
|
@ -1224,20 +1239,22 @@ void RBBIRuleScanner::scanSet() {
|
||||||
RBBIDebugPrintf("UnicodeSet parse position.ErrorIndex = %d\n", pos.getIndex());
|
RBBIDebugPrintf("UnicodeSet parse position.ErrorIndex = %d\n", pos.getIndex());
|
||||||
#endif
|
#endif
|
||||||
error(localStatus);
|
error(localStatus);
|
||||||
delete uset;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the set contains at least one code point.
|
// Verify that the set contains at least one code point.
|
||||||
//
|
//
|
||||||
U_ASSERT(uset!=nullptr);
|
U_ASSERT(uset.isValid());
|
||||||
if (uset->isEmpty()) {
|
UnicodeSet tempSet(*uset);
|
||||||
|
// Use tempSet to handle the case that the UnicodeSet contains
|
||||||
|
// only string element, such as [{ab}] and treat it as empty set.
|
||||||
|
tempSet.removeAllStrings();
|
||||||
|
if (tempSet.isEmpty()) {
|
||||||
// This set is empty.
|
// This set is empty.
|
||||||
// Make it an error, because it almost certainly is not what the user wanted.
|
// Make it an error, because it almost certainly is not what the user wanted.
|
||||||
// Also, avoids having to think about corner cases in the tree manipulation code
|
// Also, avoids having to think about corner cases in the tree manipulation code
|
||||||
// that occurs later on.
|
// that occurs later on.
|
||||||
error(U_BRK_RULE_EMPTY_SET);
|
error(U_BRK_RULE_EMPTY_SET);
|
||||||
delete uset;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,7 +1263,7 @@ void RBBIRuleScanner::scanSet() {
|
||||||
// Don't just set fScanIndex because the line/char positions maintained
|
// Don't just set fScanIndex because the line/char positions maintained
|
||||||
// for error reporting would be thrown off.
|
// for error reporting would be thrown off.
|
||||||
i = pos.getIndex();
|
i = pos.getIndex();
|
||||||
for (;;) {
|
for (;U_SUCCESS(*fRB->fStatus);) {
|
||||||
if (fNextIndex >= i) {
|
if (fNextIndex >= i) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1269,7 +1286,7 @@ void RBBIRuleScanner::scanSet() {
|
||||||
// character categories for run time engine.
|
// character categories for run time engine.
|
||||||
// - Eliminates mulitiple instances of the same set.
|
// - Eliminates mulitiple instances of the same set.
|
||||||
// - Creates a new uset node if necessary (if this isn't a duplicate.)
|
// - Creates a new uset node if necessary (if this isn't a duplicate.)
|
||||||
findSetFor(n->fText, n, uset);
|
findSetFor(n->fText, n, uset.orphan());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ const UnicodeFunctor *RBBISymbolTable::lookupMatcher(UChar32 ch) const
|
||||||
RBBISymbolTable *This = (RBBISymbolTable *)this; // cast off const
|
RBBISymbolTable *This = (RBBISymbolTable *)this; // cast off const
|
||||||
if (ch == 0xffff) {
|
if (ch == 0xffff) {
|
||||||
retVal = fCachedSetLookup;
|
retVal = fCachedSetLookup;
|
||||||
This->fCachedSetLookup = 0;
|
This->fCachedSetLookup = nullptr;
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,10 @@ void RBBITableBuilder::buildForwardTable() {
|
||||||
// Walk through the tree, replacing any references to $variables with a copy of the
|
// Walk through the tree, replacing any references to $variables with a copy of the
|
||||||
// parse tree for the substitution expression.
|
// parse tree for the substitution expression.
|
||||||
//
|
//
|
||||||
fTree = fTree->flattenVariables();
|
fTree = fTree->flattenVariables(*fStatus, 0);
|
||||||
|
if (U_FAILURE(*fStatus)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
#ifdef RBBI_DEBUG
|
#ifdef RBBI_DEBUG
|
||||||
if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ftree")) {
|
if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ftree")) {
|
||||||
RBBIDebugPuts("\nParse tree after flattening variable references.");
|
RBBIDebugPuts("\nParse tree after flattening variable references.");
|
||||||
|
|
|
@ -179,7 +179,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ResourceBundle)
|
||||||
ResourceBundle::ResourceBundle(UErrorCode &err)
|
ResourceBundle::ResourceBundle(UErrorCode &err)
|
||||||
:UObject(), fLocale(nullptr)
|
:UObject(), fLocale(nullptr)
|
||||||
{
|
{
|
||||||
fResource = ures_open(0, Locale::getDefault().getName(), &err);
|
fResource = ures_open(nullptr, Locale::getDefault().getName(), &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceBundle::ResourceBundle(const ResourceBundle &other)
|
ResourceBundle::ResourceBundle(const ResourceBundle &other)
|
||||||
|
@ -188,7 +188,7 @@ ResourceBundle::ResourceBundle(const ResourceBundle &other)
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
if (other.fResource) {
|
if (other.fResource) {
|
||||||
fResource = ures_copyResb(0, other.fResource, &status);
|
fResource = ures_copyResb(nullptr, other.fResource, &status);
|
||||||
} else {
|
} else {
|
||||||
/* Copying a bad resource bundle */
|
/* Copying a bad resource bundle */
|
||||||
fResource = nullptr;
|
fResource = nullptr;
|
||||||
|
@ -199,7 +199,7 @@ ResourceBundle::ResourceBundle(UResourceBundle *res, UErrorCode& err)
|
||||||
:UObject(), fLocale(nullptr)
|
:UObject(), fLocale(nullptr)
|
||||||
{
|
{
|
||||||
if (res) {
|
if (res) {
|
||||||
fResource = ures_copyResb(0, res, &err);
|
fResource = ures_copyResb(nullptr, res, &err);
|
||||||
} else {
|
} else {
|
||||||
/* Copying a bad resource bundle */
|
/* Copying a bad resource bundle */
|
||||||
fResource = nullptr;
|
fResource = nullptr;
|
||||||
|
@ -218,7 +218,7 @@ ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
|
||||||
if(this == &other) {
|
if(this == &other) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
if(fResource != 0) {
|
if (fResource != nullptr) {
|
||||||
ures_close(fResource);
|
ures_close(fResource);
|
||||||
fResource = nullptr;
|
fResource = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
|
||||||
}
|
}
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
if (other.fResource) {
|
if (other.fResource) {
|
||||||
fResource = ures_copyResb(0, other.fResource, &status);
|
fResource = ures_copyResb(nullptr, other.fResource, &status);
|
||||||
} else {
|
} else {
|
||||||
/* Copying a bad resource bundle */
|
/* Copying a bad resource bundle */
|
||||||
fResource = nullptr;
|
fResource = nullptr;
|
||||||
|
@ -238,12 +238,10 @@ ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
|
||||||
|
|
||||||
ResourceBundle::~ResourceBundle()
|
ResourceBundle::~ResourceBundle()
|
||||||
{
|
{
|
||||||
if(fResource != 0) {
|
if (fResource != nullptr) {
|
||||||
ures_close(fResource);
|
ures_close(fResource);
|
||||||
}
|
}
|
||||||
if(fLocale != nullptr) {
|
delete fLocale;
|
||||||
delete(fLocale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceBundle *
|
ResourceBundle *
|
||||||
|
@ -311,7 +309,7 @@ ResourceBundle ResourceBundle::getNext(UErrorCode& status) {
|
||||||
|
|
||||||
UnicodeString ResourceBundle::getNextString(UErrorCode& status) {
|
UnicodeString ResourceBundle::getNextString(UErrorCode& status) {
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
const char16_t* r = ures_getNextString(fResource, &len, 0, &status);
|
const char16_t* r = ures_getNextString(fResource, &len, nullptr, &status);
|
||||||
return UnicodeString(true, r, len);
|
return UnicodeString(true, r, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@ RuleCharacterIterator::RuleCharacterIterator(const UnicodeString& theText, const
|
||||||
text(theText),
|
text(theText),
|
||||||
pos(thePos),
|
pos(thePos),
|
||||||
sym(theSym),
|
sym(theSym),
|
||||||
buf(0),
|
buf(nullptr),
|
||||||
bufPos(0)
|
bufPos(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
UBool RuleCharacterIterator::atEnd() const {
|
UBool RuleCharacterIterator::atEnd() const {
|
||||||
return buf == 0 && pos.getIndex() == text.length();
|
return buf == nullptr && pos.getIndex() == text.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
UChar32 RuleCharacterIterator::next(int32_t options, UBool& isEscaped, UErrorCode& ec) {
|
UChar32 RuleCharacterIterator::next(int32_t options, UBool& isEscaped, UErrorCode& ec) {
|
||||||
|
@ -45,8 +45,8 @@ UChar32 RuleCharacterIterator::next(int32_t options, UBool& isEscaped, UErrorCod
|
||||||
c = _current();
|
c = _current();
|
||||||
_advance(U16_LENGTH(c));
|
_advance(U16_LENGTH(c));
|
||||||
|
|
||||||
if (c == SymbolTable::SYMBOL_REF && buf == 0 &&
|
if (c == SymbolTable::SYMBOL_REF && buf == nullptr &&
|
||||||
(options & PARSE_VARIABLES) != 0 && sym != 0) {
|
(options & PARSE_VARIABLES) != 0 && sym != nullptr) {
|
||||||
UnicodeString name = sym->parseReference(text, pos, text.length());
|
UnicodeString name = sym->parseReference(text, pos, text.length());
|
||||||
// If name is empty there was an isolated SYMBOL_REF;
|
// If name is empty there was an isolated SYMBOL_REF;
|
||||||
// return it. Caller must be prepared for this.
|
// return it. Caller must be prepared for this.
|
||||||
|
@ -55,13 +55,13 @@ UChar32 RuleCharacterIterator::next(int32_t options, UBool& isEscaped, UErrorCod
|
||||||
}
|
}
|
||||||
bufPos = 0;
|
bufPos = 0;
|
||||||
buf = sym->lookup(name);
|
buf = sym->lookup(name);
|
||||||
if (buf == 0) {
|
if (buf == nullptr) {
|
||||||
ec = U_UNDEFINED_VARIABLE;
|
ec = U_UNDEFINED_VARIABLE;
|
||||||
return DONE;
|
return DONE;
|
||||||
}
|
}
|
||||||
// Handle empty variable value
|
// Handle empty variable value
|
||||||
if (buf->length() == 0) {
|
if (buf->length() == 0) {
|
||||||
buf = 0;
|
buf = nullptr;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ UnicodeString& RuleCharacterIterator::lookahead(UnicodeString& result, int32_t m
|
||||||
if (maxLookAhead < 0) {
|
if (maxLookAhead < 0) {
|
||||||
maxLookAhead = 0x7FFFFFFF;
|
maxLookAhead = 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
if (buf != 0) {
|
if (buf != nullptr) {
|
||||||
buf->extract(bufPos, maxLookAhead, result);
|
buf->extract(bufPos, maxLookAhead, result);
|
||||||
} else {
|
} else {
|
||||||
text.extract(pos.getIndex(), maxLookAhead, result);
|
text.extract(pos.getIndex(), maxLookAhead, result);
|
||||||
|
@ -135,7 +135,7 @@ UnicodeString& RuleCharacterIterator::toString(UnicodeString& result) const {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UChar32 RuleCharacterIterator::_current() const {
|
UChar32 RuleCharacterIterator::_current() const {
|
||||||
if (buf != 0) {
|
if (buf != nullptr) {
|
||||||
return buf->char32At(bufPos);
|
return buf->char32At(bufPos);
|
||||||
} else {
|
} else {
|
||||||
int i = pos.getIndex();
|
int i = pos.getIndex();
|
||||||
|
@ -144,10 +144,10 @@ UChar32 RuleCharacterIterator::_current() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleCharacterIterator::_advance(int32_t count) {
|
void RuleCharacterIterator::_advance(int32_t count) {
|
||||||
if (buf != 0) {
|
if (buf != nullptr) {
|
||||||
bufPos += count;
|
bufPos += count;
|
||||||
if (bufPos == buf->length()) {
|
if (bufPos == buf->length()) {
|
||||||
buf = 0;
|
buf = nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pos.setIndex(pos.getIndex() + count);
|
pos.setIndex(pos.getIndex() + count);
|
||||||
|
|
|
@ -224,7 +224,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
inline UBool RuleCharacterIterator::inVariable() const {
|
inline UBool RuleCharacterIterator::inVariable() const {
|
||||||
return buf != 0;
|
return buf != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
|
|
@ -244,7 +244,6 @@ ubidi_setLine(const UBiDi *pParaBiDi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pLineBiDi->pParaBiDi=pParaBiDi; /* mark successful setLine */
|
pLineBiDi->pParaBiDi=pParaBiDi; /* mark successful setLine */
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI UBiDiLevel U_EXPORT2
|
U_CAPI UBiDiLevel U_EXPORT2
|
||||||
|
|
|
@ -38,9 +38,9 @@ ubrk_open(UBreakIteratorType type,
|
||||||
UErrorCode *status)
|
UErrorCode *status)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(U_FAILURE(*status)) return 0;
|
if (U_FAILURE(*status)) return nullptr;
|
||||||
|
|
||||||
BreakIterator *result = 0;
|
BreakIterator *result = nullptr;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
|
||||||
|
@ -70,11 +70,11 @@ ubrk_open(UBreakIteratorType type,
|
||||||
|
|
||||||
// check for allocation error
|
// check for allocation error
|
||||||
if (U_FAILURE(*status)) {
|
if (U_FAILURE(*status)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if(result == 0) {
|
if (result == nullptr) {
|
||||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,14 +102,14 @@ ubrk_openRules( const char16_t *rules,
|
||||||
UErrorCode *status) {
|
UErrorCode *status) {
|
||||||
|
|
||||||
if (status == nullptr || U_FAILURE(*status)){
|
if (status == nullptr || U_FAILURE(*status)){
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BreakIterator *result = 0;
|
BreakIterator *result = nullptr;
|
||||||
UnicodeString ruleString(rules, rulesLength);
|
UnicodeString ruleString(rules, rulesLength);
|
||||||
result = RBBIRuleBuilder::createRuleBasedBreakIterator(ruleString, parseErr, *status);
|
result = RBBIRuleBuilder::createRuleBasedBreakIterator(ruleString, parseErr, *status);
|
||||||
if(U_FAILURE(*status)) {
|
if(U_FAILURE(*status)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
UBreakIterator *uBI = (UBreakIterator *)result;
|
UBreakIterator *uBI = (UBreakIterator *)result;
|
||||||
|
|
|
@ -357,7 +357,7 @@ enum {
|
||||||
/* definitions for 16-bit case properties word ------------------------------ */
|
/* definitions for 16-bit case properties word ------------------------------ */
|
||||||
|
|
||||||
U_CFUNC const UTrie2 * U_EXPORT2
|
U_CFUNC const UTrie2 * U_EXPORT2
|
||||||
ucase_getTrie();
|
ucase_getTrie(void);
|
||||||
|
|
||||||
/* 2-bit constants for types of cased characters */
|
/* 2-bit constants for types of cased characters */
|
||||||
#define UCASE_TYPE_MASK 3
|
#define UCASE_TYPE_MASK 3
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "uassert.h"
|
#include "uassert.h"
|
||||||
#include "ucase.h"
|
#include "ucase.h"
|
||||||
#include "ucasemap_imp.h"
|
#include "ucasemap_imp.h"
|
||||||
#include "ustr_imp.h"
|
|
||||||
|
|
||||||
U_NAMESPACE_USE
|
U_NAMESPACE_USE
|
||||||
|
|
||||||
|
@ -917,21 +916,20 @@ ucasemap_mapUTF8(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_P
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckedArrayByteSink sink(dest, destCapacity);
|
|
||||||
if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
|
if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
|
||||||
edits->reset();
|
edits->reset();
|
||||||
}
|
}
|
||||||
|
int32_t reslen = ByteSinkUtil::viaByteSinkToTerminatedChars(
|
||||||
|
dest, destCapacity,
|
||||||
|
[&](ByteSink& sink, UErrorCode& status) {
|
||||||
stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
|
stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
|
||||||
(const uint8_t *)src, srcLength, sink, edits, errorCode);
|
(const uint8_t *)src, srcLength, sink, edits, status);
|
||||||
sink.Flush();
|
},
|
||||||
if (U_SUCCESS(errorCode)) {
|
errorCode);
|
||||||
if (sink.Overflowed()) {
|
if (U_SUCCESS(errorCode) && edits != nullptr) {
|
||||||
errorCode = U_BUFFER_OVERFLOW_ERROR;
|
|
||||||
} else if (edits != nullptr) {
|
|
||||||
edits->copyErrorTo(errorCode);
|
edits->copyErrorTo(errorCode);
|
||||||
}
|
}
|
||||||
}
|
return reslen;
|
||||||
return u_terminateChars(dest, destCapacity, sink.NumberOfBytesAppended(), &errorCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public API functions */
|
/* public API functions */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,14 +20,14 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)
|
||||||
|
|
||||||
UCharCharacterIterator::UCharCharacterIterator()
|
UCharCharacterIterator::UCharCharacterIterator()
|
||||||
: CharacterIterator(),
|
: CharacterIterator(),
|
||||||
text(0)
|
text(nullptr)
|
||||||
{
|
{
|
||||||
// never default construct!
|
// never default construct!
|
||||||
}
|
}
|
||||||
|
|
||||||
UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
|
UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
|
||||||
int32_t length)
|
int32_t length)
|
||||||
: CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0),
|
: CharacterIterator(textPtr != nullptr ? (length >= 0 ? length : u_strlen(textPtr)) : 0),
|
||||||
text(textPtr)
|
text(textPtr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
|
||||||
UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
|
UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
|
||||||
int32_t length,
|
int32_t length,
|
||||||
int32_t position)
|
int32_t position)
|
||||||
: CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position),
|
: CharacterIterator(textPtr != nullptr ? (length >= 0 ? length : u_strlen(textPtr)) : 0, position),
|
||||||
text(textPtr)
|
text(textPtr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,8 @@ UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
|
||||||
int32_t textBegin,
|
int32_t textBegin,
|
||||||
int32_t textEnd,
|
int32_t textEnd,
|
||||||
int32_t position)
|
int32_t position)
|
||||||
: CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position),
|
: CharacterIterator(textPtr != nullptr ? (length >= 0 ? length : u_strlen(textPtr)) : 0,
|
||||||
|
textBegin, textEnd, position),
|
||||||
text(textPtr)
|
text(textPtr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -352,7 +353,7 @@ UCharCharacterIterator::move32(int32_t delta, CharacterIterator::EOrigin origin)
|
||||||
void UCharCharacterIterator::setText(ConstChar16Ptr newText,
|
void UCharCharacterIterator::setText(ConstChar16Ptr newText,
|
||||||
int32_t newTextLength) {
|
int32_t newTextLength) {
|
||||||
text = newText;
|
text = newText;
|
||||||
if(newText == 0 || newTextLength < 0) {
|
if (newText == nullptr || newTextLength < 0) {
|
||||||
newTextLength = 0;
|
newTextLength = 0;
|
||||||
}
|
}
|
||||||
end = textLength = newTextLength;
|
end = textLength = newTextLength;
|
||||||
|
|
|
@ -473,8 +473,6 @@ ucnv_setSubstChars (UConverter * converter,
|
||||||
* we set subChar1 to 0.
|
* we set subChar1 to 0.
|
||||||
*/
|
*/
|
||||||
converter->subChar1 = 0;
|
converter->subChar1 = 0;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_CAPI void U_EXPORT2
|
||||||
|
@ -1754,7 +1752,7 @@ ucnv_fromUChars(UConverter *cnv,
|
||||||
destLimit=dest+destCapacity;
|
destLimit=dest+destCapacity;
|
||||||
|
|
||||||
/* perform the conversion */
|
/* perform the conversion */
|
||||||
ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, true, pErrorCode);
|
ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, nullptr, true, pErrorCode);
|
||||||
destLength=(int32_t)(dest-originalDest);
|
destLength=(int32_t)(dest-originalDest);
|
||||||
|
|
||||||
/* if an overflow occurs, then get the preflighting length */
|
/* if an overflow occurs, then get the preflighting length */
|
||||||
|
@ -1765,7 +1763,7 @@ ucnv_fromUChars(UConverter *cnv,
|
||||||
do {
|
do {
|
||||||
dest=buffer;
|
dest=buffer;
|
||||||
*pErrorCode=U_ZERO_ERROR;
|
*pErrorCode=U_ZERO_ERROR;
|
||||||
ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, true, pErrorCode);
|
ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, nullptr, true, pErrorCode);
|
||||||
destLength+=(int32_t)(dest-buffer);
|
destLength+=(int32_t)(dest-buffer);
|
||||||
} while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
|
} while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -1810,7 +1808,7 @@ ucnv_toUChars(UConverter *cnv,
|
||||||
destLimit=dest+destCapacity;
|
destLimit=dest+destCapacity;
|
||||||
|
|
||||||
/* perform the conversion */
|
/* perform the conversion */
|
||||||
ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, true, pErrorCode);
|
ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, nullptr, true, pErrorCode);
|
||||||
destLength=(int32_t)(dest-originalDest);
|
destLength=(int32_t)(dest-originalDest);
|
||||||
|
|
||||||
/* if an overflow occurs, then get the preflighting length */
|
/* if an overflow occurs, then get the preflighting length */
|
||||||
|
@ -1822,7 +1820,7 @@ ucnv_toUChars(UConverter *cnv,
|
||||||
do {
|
do {
|
||||||
dest=buffer;
|
dest=buffer;
|
||||||
*pErrorCode=U_ZERO_ERROR;
|
*pErrorCode=U_ZERO_ERROR;
|
||||||
ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, true, pErrorCode);
|
ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, nullptr, true, pErrorCode);
|
||||||
destLength+=(int32_t)(dest-buffer);
|
destLength+=(int32_t)(dest-buffer);
|
||||||
}
|
}
|
||||||
while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
|
while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
|
||||||
|
|
|
@ -109,7 +109,6 @@ UCNV_FROM_U_CALLBACK_STOP (
|
||||||
*err = U_ZERO_ERROR;
|
*err = U_ZERO_ERROR;
|
||||||
}
|
}
|
||||||
/* the caller must have set the error code accordingly */
|
/* the caller must have set the error code accordingly */
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,7 +124,6 @@ UCNV_TO_U_CALLBACK_STOP (
|
||||||
{
|
{
|
||||||
/* the caller must have set the error code accordingly */
|
/* the caller must have set the error code accordingly */
|
||||||
(void)context; (void)toUArgs; (void)codePoints; (void)length; (void)reason; (void)err;
|
(void)context; (void)toUArgs; (void)codePoints; (void)length; (void)reason; (void)err;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_CAPI void U_EXPORT2
|
||||||
|
@ -353,8 +351,6 @@ UCNV_FROM_U_CALLBACK_ESCAPE (
|
||||||
*err = err2;
|
*err = err2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -455,7 +455,6 @@ unicodeMode:
|
||||||
pArgs->source=(const char *)source;
|
pArgs->source=(const char *)source;
|
||||||
pArgs->target=target;
|
pArgs->target=target;
|
||||||
pArgs->offsets=offsets;
|
pArgs->offsets=offsets;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void U_CALLCONV
|
static void U_CALLCONV
|
||||||
|
@ -731,7 +730,6 @@ unicodeMode:
|
||||||
pArgs->source=source;
|
pArgs->source=source;
|
||||||
pArgs->target=(char *)target;
|
pArgs->target=(char *)target;
|
||||||
pArgs->offsets=offsets;
|
pArgs->offsets=offsets;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * U_CALLCONV
|
static const char * U_CALLCONV
|
||||||
|
@ -1156,7 +1154,6 @@ endloop:
|
||||||
pArgs->source=(const char *)source;
|
pArgs->source=(const char *)source;
|
||||||
pArgs->target=target;
|
pArgs->target=target;
|
||||||
pArgs->offsets=offsets;
|
pArgs->offsets=offsets;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void U_CALLCONV
|
static void U_CALLCONV
|
||||||
|
@ -1443,7 +1440,6 @@ unicodeMode:
|
||||||
pArgs->source=source;
|
pArgs->source=source;
|
||||||
pArgs->target=(char *)target;
|
pArgs->target=(char *)target;
|
||||||
pArgs->offsets=offsets;
|
pArgs->offsets=offsets;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
U_CDECL_END
|
U_CDECL_END
|
||||||
|
|
||||||
|
|
|
@ -1165,7 +1165,6 @@ endloop:
|
||||||
pArgs->source=(const char *)source;
|
pArgs->source=(const char *)source;
|
||||||
pArgs->target=target;
|
pArgs->target=target;
|
||||||
pArgs->offsets=offsets;
|
pArgs->offsets=offsets;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1363,7 +1362,6 @@ endloop:
|
||||||
/* write back the updated pointers */
|
/* write back the updated pointers */
|
||||||
pArgs->source=(const char *)source;
|
pArgs->source=(const char *)source;
|
||||||
pArgs->target=target;
|
pArgs->target=target;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* miscellaneous ------------------------------------------------------------ */
|
/* miscellaneous ------------------------------------------------------------ */
|
||||||
|
|
|
@ -1537,12 +1537,12 @@ _ISCII_SafeClone(const UConverter *cnv,
|
||||||
int32_t bufferSizeNeeded = sizeof(struct cloneISCIIStruct);
|
int32_t bufferSizeNeeded = sizeof(struct cloneISCIIStruct);
|
||||||
|
|
||||||
if (U_FAILURE(*status)) {
|
if (U_FAILURE(*status)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pBufferSize == 0) { /* 'preflighting' request - set needed size into *pBufferSize */
|
if (*pBufferSize == 0) { /* 'preflighting' request - set needed size into *pBufferSize */
|
||||||
*pBufferSize = bufferSizeNeeded;
|
*pBufferSize = bufferSizeNeeded;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
localClone = (struct cloneISCIIStruct *)stackBuffer;
|
localClone = (struct cloneISCIIStruct *)stackBuffer;
|
||||||
|
|
|
@ -572,7 +572,6 @@ endloop:
|
||||||
pArgs->source=(const char *)source;
|
pArgs->source=(const char *)source;
|
||||||
pArgs->target=target;
|
pArgs->target=target;
|
||||||
pArgs->offsets=offsets;
|
pArgs->offsets=offsets;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -864,7 +863,6 @@ endloop:
|
||||||
/* write back the updated pointers */
|
/* write back the updated pointers */
|
||||||
pArgs->source=(const char *)source;
|
pArgs->source=(const char *)source;
|
||||||
pArgs->target=target;
|
pArgs->target=target;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
U_CDECL_END
|
U_CDECL_END
|
||||||
/* SCSU-from-Unicode conversion functions ----------------------------------- */
|
/* SCSU-from-Unicode conversion functions ----------------------------------- */
|
||||||
|
@ -1978,12 +1976,12 @@ _SCSUSafeClone(const UConverter *cnv,
|
||||||
int32_t bufferSizeNeeded = sizeof(struct cloneSCSUStruct);
|
int32_t bufferSizeNeeded = sizeof(struct cloneSCSUStruct);
|
||||||
|
|
||||||
if (U_FAILURE(*status)){
|
if (U_FAILURE(*status)){
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||||
*pBufferSize = bufferSizeNeeded;
|
*pBufferSize = bufferSizeNeeded;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
localClone = (struct cloneSCSUStruct *)stackBuffer;
|
localClone = (struct cloneSCSUStruct *)stackBuffer;
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "unicode/usetiter.h"
|
#include "unicode/usetiter.h"
|
||||||
#include "unicode/utf16.h"
|
#include "unicode/utf16.h"
|
||||||
#include "ustr_imp.h"
|
#include "ustr_imp.h"
|
||||||
#include "bytesinkutil.h"
|
|
||||||
#include "charstr.h"
|
#include "charstr.h"
|
||||||
#include "cmemory.h"
|
#include "cmemory.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
|
@ -296,7 +295,7 @@ myUCharsToChars(char* resultOfLen4, const char16_t* currency) {
|
||||||
static const int32_t*
|
static const int32_t*
|
||||||
_findMetaData(const char16_t* currency, UErrorCode& ec) {
|
_findMetaData(const char16_t* currency, UErrorCode& ec) {
|
||||||
|
|
||||||
if (currency == 0 || *currency == 0) {
|
if (currency == nullptr || *currency == 0) {
|
||||||
if (U_SUCCESS(ec)) {
|
if (U_SUCCESS(ec)) {
|
||||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -349,10 +348,10 @@ _findMetaData(const char16_t* currency, UErrorCode& ec) {
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
static void
|
static CharString
|
||||||
idForLocale(const char* locale, char* countryAndVariant, int capacity, UErrorCode* ec)
|
idForLocale(const char* locale, UErrorCode* ec)
|
||||||
{
|
{
|
||||||
ulocimp_getRegionForSupplementalData(locale, false, countryAndVariant, capacity, ec);
|
return ulocimp_getRegionForSupplementalData(locale, false, *ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------
|
// ------------------------------------------
|
||||||
|
@ -371,7 +370,7 @@ U_CDECL_END
|
||||||
struct CReg;
|
struct CReg;
|
||||||
|
|
||||||
static UMutex gCRegLock;
|
static UMutex gCRegLock;
|
||||||
static CReg* gCRegHead = 0;
|
static CReg* gCRegHead = nullptr;
|
||||||
|
|
||||||
struct CReg : public icu::UMemory {
|
struct CReg : public icu::UMemory {
|
||||||
CReg *next;
|
CReg *next;
|
||||||
|
@ -379,7 +378,7 @@ struct CReg : public icu::UMemory {
|
||||||
char id[ULOC_FULLNAME_CAPACITY];
|
char id[ULOC_FULLNAME_CAPACITY];
|
||||||
|
|
||||||
CReg(const char16_t* _iso, const char* _id)
|
CReg(const char16_t* _iso, const char* _id)
|
||||||
: next(0)
|
: next(nullptr)
|
||||||
{
|
{
|
||||||
int32_t len = (int32_t)uprv_strlen(_id);
|
int32_t len = (int32_t)uprv_strlen(_id);
|
||||||
if (len > (int32_t)(sizeof(id)-1)) {
|
if (len > (int32_t)(sizeof(id)-1)) {
|
||||||
|
@ -408,7 +407,7 @@ struct CReg : public icu::UMemory {
|
||||||
}
|
}
|
||||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
}
|
}
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool unreg(UCurrRegistryKey key) {
|
static UBool unreg(UCurrRegistryKey key) {
|
||||||
|
@ -464,9 +463,8 @@ U_CAPI UCurrRegistryKey U_EXPORT2
|
||||||
ucurr_register(const char16_t* isoCode, const char* locale, UErrorCode *status)
|
ucurr_register(const char16_t* isoCode, const char* locale, UErrorCode *status)
|
||||||
{
|
{
|
||||||
if (status && U_SUCCESS(*status)) {
|
if (status && U_SUCCESS(*status)) {
|
||||||
char id[ULOC_FULLNAME_CAPACITY];
|
CharString id = idForLocale(locale, status);
|
||||||
idForLocale(locale, id, sizeof(id), status);
|
return CReg::reg(isoCode, id.data(), status);
|
||||||
return CReg::reg(isoCode, id, status);
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -524,11 +522,7 @@ ucurr_forLocale(const char* locale,
|
||||||
}
|
}
|
||||||
|
|
||||||
UErrorCode localStatus = U_ZERO_ERROR;
|
UErrorCode localStatus = U_ZERO_ERROR;
|
||||||
CharString currency;
|
CharString currency = ulocimp_getKeywordValue(locale, "currency", localStatus);
|
||||||
{
|
|
||||||
CharStringByteSink sink(¤cy);
|
|
||||||
ulocimp_getKeywordValue(locale, "currency", sink, &localStatus);
|
|
||||||
}
|
|
||||||
int32_t resLen = currency.length();
|
int32_t resLen = currency.length();
|
||||||
|
|
||||||
if (U_SUCCESS(localStatus) && resLen == 3 && uprv_isInvariantString(currency.data(), resLen)) {
|
if (U_SUCCESS(localStatus) && resLen == 3 && uprv_isInvariantString(currency.data(), resLen)) {
|
||||||
|
@ -540,14 +534,13 @@ ucurr_forLocale(const char* locale,
|
||||||
}
|
}
|
||||||
|
|
||||||
// get country or country_variant in `id'
|
// get country or country_variant in `id'
|
||||||
char id[ULOC_FULLNAME_CAPACITY];
|
CharString id = idForLocale(locale, ec);
|
||||||
idForLocale(locale, id, UPRV_LENGTHOF(id), ec);
|
|
||||||
if (U_FAILURE(*ec)) {
|
if (U_FAILURE(*ec)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !UCONFIG_NO_SERVICE
|
#if !UCONFIG_NO_SERVICE
|
||||||
const char16_t* result = CReg::get(id);
|
const char16_t* result = CReg::get(id.data());
|
||||||
if (result) {
|
if (result) {
|
||||||
if(buffCapacity > u_strlen(result)) {
|
if(buffCapacity > u_strlen(result)) {
|
||||||
u_strcpy(buff, result);
|
u_strcpy(buff, result);
|
||||||
|
@ -557,13 +550,13 @@ ucurr_forLocale(const char* locale,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Remove variants, which is only needed for registration.
|
// Remove variants, which is only needed for registration.
|
||||||
char *idDelim = uprv_strchr(id, VAR_DELIM);
|
char *idDelim = uprv_strchr(id.data(), VAR_DELIM);
|
||||||
if (idDelim) {
|
if (idDelim) {
|
||||||
idDelim[0] = 0;
|
id.truncate(idDelim - id.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char16_t* s = nullptr; // Currency code from data file.
|
const char16_t* s = nullptr; // Currency code from data file.
|
||||||
if (id[0] == 0) {
|
if (id.isEmpty()) {
|
||||||
// No point looking in the data for an empty string.
|
// No point looking in the data for an empty string.
|
||||||
// This is what we would get.
|
// This is what we would get.
|
||||||
localStatus = U_MISSING_RESOURCE_ERROR;
|
localStatus = U_MISSING_RESOURCE_ERROR;
|
||||||
|
@ -572,7 +565,7 @@ ucurr_forLocale(const char* locale,
|
||||||
localStatus = U_ZERO_ERROR;
|
localStatus = U_ZERO_ERROR;
|
||||||
UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
|
UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
|
||||||
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
||||||
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
|
UResourceBundle *countryArray = ures_getByKey(rb, id.data(), cm, &localStatus);
|
||||||
// https://unicode-org.atlassian.net/browse/ICU-21997
|
// https://unicode-org.atlassian.net/browse/ICU-21997
|
||||||
// Prefer to use currencies that are legal tender.
|
// Prefer to use currencies that are legal tender.
|
||||||
if (U_SUCCESS(localStatus)) {
|
if (U_SUCCESS(localStatus)) {
|
||||||
|
@ -602,13 +595,9 @@ ucurr_forLocale(const char* locale,
|
||||||
ures_close(countryArray);
|
ures_close(countryArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((U_FAILURE(localStatus)) && strchr(id, '_') != 0) {
|
if ((U_FAILURE(localStatus)) && strchr(id.data(), '_') != nullptr) {
|
||||||
// We don't know about it. Check to see if we support the variant.
|
// We don't know about it. Check to see if we support the variant.
|
||||||
CharString parent;
|
CharString parent = ulocimp_getParent(locale, *ec);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&parent);
|
|
||||||
ulocimp_getParent(locale, sink, ec);
|
|
||||||
}
|
|
||||||
*ec = U_USING_FALLBACK_WARNING;
|
*ec = U_USING_FALLBACK_WARNING;
|
||||||
// TODO: Loop over the parent rather than recursing and
|
// TODO: Loop over the parent rather than recursing and
|
||||||
// looking again for a currency keyword.
|
// looking again for a currency keyword.
|
||||||
|
@ -647,10 +636,7 @@ static UBool fallback(CharString& loc) {
|
||||||
loc.truncate(3);
|
loc.truncate(3);
|
||||||
loc.append("001", status);
|
loc.append("001", status);
|
||||||
} else {
|
} else {
|
||||||
CharString tmp;
|
loc = ulocimp_getParent(loc.data(), status);
|
||||||
CharStringByteSink sink(&tmp);
|
|
||||||
ulocimp_getParent(loc.data(), sink, &status);
|
|
||||||
loc = std::move(tmp);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
char *i = uprv_strrchr(loc, '_');
|
char *i = uprv_strrchr(loc, '_');
|
||||||
|
@ -683,13 +669,13 @@ ucurr_getName(const char16_t* currency,
|
||||||
//|}
|
//|}
|
||||||
|
|
||||||
if (U_FAILURE(*ec)) {
|
if (U_FAILURE(*ec)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t choice = (int32_t) nameStyle;
|
int32_t choice = (int32_t) nameStyle;
|
||||||
if (choice < 0 || choice > 4) {
|
if (choice < 0 || choice > 4) {
|
||||||
*ec = U_ILLEGAL_ARGUMENT_ERROR;
|
*ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the future, resource bundles may implement multi-level
|
// In the future, resource bundles may implement multi-level
|
||||||
|
@ -705,14 +691,10 @@ ucurr_getName(const char16_t* currency,
|
||||||
// this function.
|
// this function.
|
||||||
UErrorCode ec2 = U_ZERO_ERROR;
|
UErrorCode ec2 = U_ZERO_ERROR;
|
||||||
|
|
||||||
CharString loc;
|
CharString loc = ulocimp_getName(locale, ec2);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&loc);
|
|
||||||
ulocimp_getName(locale, sink, &ec2);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(ec2)) {
|
if (U_FAILURE(ec2)) {
|
||||||
*ec = U_ILLEGAL_ARGUMENT_ERROR;
|
*ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[ISO_CURRENCY_CODE_LENGTH+1];
|
char buf[ISO_CURRENCY_CODE_LENGTH+1];
|
||||||
|
@ -739,7 +721,7 @@ ucurr_getName(const char16_t* currency,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*ec = U_UNSUPPORTED_ERROR;
|
*ec = U_UNSUPPORTED_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
key.append("/", ec2);
|
key.append("/", ec2);
|
||||||
key.append(buf, ec2);
|
key.append(buf, ec2);
|
||||||
|
@ -800,21 +782,17 @@ ucurr_getPluralName(const char16_t* currency,
|
||||||
//|}
|
//|}
|
||||||
|
|
||||||
if (U_FAILURE(*ec)) {
|
if (U_FAILURE(*ec)) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a separate UErrorCode here that does not propagate out of
|
// Use a separate UErrorCode here that does not propagate out of
|
||||||
// this function.
|
// this function.
|
||||||
UErrorCode ec2 = U_ZERO_ERROR;
|
UErrorCode ec2 = U_ZERO_ERROR;
|
||||||
|
|
||||||
CharString loc;
|
CharString loc = ulocimp_getName(locale, ec2);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&loc);
|
|
||||||
ulocimp_getName(locale, sink, &ec2);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(ec2)) {
|
if (U_FAILURE(ec2)) {
|
||||||
*ec = U_ILLEGAL_ARGUMENT_ERROR;
|
*ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[ISO_CURRENCY_CODE_LENGTH+1];
|
char buf[ISO_CURRENCY_CODE_LENGTH+1];
|
||||||
|
@ -1002,11 +980,7 @@ collectCurrencyNames(const char* locale,
|
||||||
// Look up the Currencies resource for the given locale.
|
// Look up the Currencies resource for the given locale.
|
||||||
UErrorCode ec2 = U_ZERO_ERROR;
|
UErrorCode ec2 = U_ZERO_ERROR;
|
||||||
|
|
||||||
CharString loc;
|
CharString loc = ulocimp_getName(locale, ec2);
|
||||||
{
|
|
||||||
CharStringByteSink sink(&loc);
|
|
||||||
ulocimp_getName(locale, sink, &ec2);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(ec2)) {
|
if (U_FAILURE(ec2)) {
|
||||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1390,7 +1364,6 @@ searchCurrencyName(const CurrencyNameStruct* currencyNames,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//========================= currency name cache =====================
|
//========================= currency name cache =====================
|
||||||
|
@ -1447,7 +1420,7 @@ currency_cache_cleanup() {
|
||||||
for (int32_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
|
for (int32_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
|
||||||
if (currCache[i]) {
|
if (currCache[i]) {
|
||||||
deleteCacheEntry(currCache[i]);
|
deleteCacheEntry(currCache[i]);
|
||||||
currCache[i] = 0;
|
currCache[i] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -2030,6 +2003,7 @@ static const struct CurrencyList {
|
||||||
{"XBC", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
{"XBC", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
||||||
{"XBD", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
{"XBD", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
||||||
{"XCD", UCURR_COMMON|UCURR_NON_DEPRECATED},
|
{"XCD", UCURR_COMMON|UCURR_NON_DEPRECATED},
|
||||||
|
{"XCG", UCURR_COMMON|UCURR_NON_DEPRECATED},
|
||||||
{"XDR", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
{"XDR", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
||||||
{"XEU", UCURR_UNCOMMON|UCURR_DEPRECATED},
|
{"XEU", UCURR_UNCOMMON|UCURR_DEPRECATED},
|
||||||
{"XFO", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
{"XFO", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
|
||||||
|
@ -2229,7 +2203,7 @@ static void U_CALLCONV initIsoCodes(UErrorCode &status) {
|
||||||
|
|
||||||
static void populateCurrSymbolsEquiv(icu::Hashtable *hash, UErrorCode &status) {
|
static void populateCurrSymbolsEquiv(icu::Hashtable *hash, UErrorCode &status) {
|
||||||
if (U_FAILURE(status)) { return; }
|
if (U_FAILURE(status)) { return; }
|
||||||
for (auto& entry : unisets::kCurrencyEntries) {
|
for (const auto& entry : unisets::kCurrencyEntries) {
|
||||||
UnicodeString exemplar(entry.exemplar);
|
UnicodeString exemplar(entry.exemplar);
|
||||||
const UnicodeSet* set = unisets::get(entry.key);
|
const UnicodeSet* set = unisets::get(entry.key);
|
||||||
if (set == nullptr) { return; }
|
if (set == nullptr) { return; }
|
||||||
|
@ -2325,10 +2299,9 @@ ucurr_countCurrencies(const char* locale,
|
||||||
{
|
{
|
||||||
// local variables
|
// local variables
|
||||||
UErrorCode localStatus = U_ZERO_ERROR;
|
UErrorCode localStatus = U_ZERO_ERROR;
|
||||||
char id[ULOC_FULLNAME_CAPACITY];
|
|
||||||
|
|
||||||
// get country or country_variant in `id'
|
// get country or country_variant in `id'
|
||||||
idForLocale(locale, id, sizeof(id), ec);
|
CharString id = idForLocale(locale, ec);
|
||||||
|
|
||||||
if (U_FAILURE(*ec))
|
if (U_FAILURE(*ec))
|
||||||
{
|
{
|
||||||
|
@ -2336,10 +2309,10 @@ ucurr_countCurrencies(const char* locale,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove variants, which is only needed for registration.
|
// Remove variants, which is only needed for registration.
|
||||||
char *idDelim = strchr(id, VAR_DELIM);
|
char *idDelim = strchr(id.data(), VAR_DELIM);
|
||||||
if (idDelim)
|
if (idDelim)
|
||||||
{
|
{
|
||||||
idDelim[0] = 0;
|
id.truncate(idDelim - id.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the CurrencyMap element in the root bundle.
|
// Look up the CurrencyMap element in the root bundle.
|
||||||
|
@ -2347,7 +2320,7 @@ ucurr_countCurrencies(const char* locale,
|
||||||
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
||||||
|
|
||||||
// Using the id derived from the local, get the currency data
|
// Using the id derived from the local, get the currency data
|
||||||
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
|
UResourceBundle *countryArray = ures_getByKey(rb, id.data(), cm, &localStatus);
|
||||||
|
|
||||||
// process each currency to see which one is valid for the given date
|
// process each currency to see which one is valid for the given date
|
||||||
if (U_SUCCESS(localStatus))
|
if (U_SUCCESS(localStatus))
|
||||||
|
@ -2440,20 +2413,19 @@ ucurr_forLocaleAndDate(const char* locale,
|
||||||
{
|
{
|
||||||
// local variables
|
// local variables
|
||||||
UErrorCode localStatus = U_ZERO_ERROR;
|
UErrorCode localStatus = U_ZERO_ERROR;
|
||||||
char id[ULOC_FULLNAME_CAPACITY];
|
|
||||||
|
|
||||||
// get country or country_variant in `id'
|
// get country or country_variant in `id'
|
||||||
idForLocale(locale, id, sizeof(id), ec);
|
CharString id = idForLocale(locale, ec);
|
||||||
if (U_FAILURE(*ec))
|
if (U_FAILURE(*ec))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove variants, which is only needed for registration.
|
// Remove variants, which is only needed for registration.
|
||||||
char *idDelim = strchr(id, VAR_DELIM);
|
char *idDelim = strchr(id.data(), VAR_DELIM);
|
||||||
if (idDelim)
|
if (idDelim)
|
||||||
{
|
{
|
||||||
idDelim[0] = 0;
|
id.truncate(idDelim - id.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the CurrencyMap element in the root bundle.
|
// Look up the CurrencyMap element in the root bundle.
|
||||||
|
@ -2461,7 +2433,7 @@ ucurr_forLocaleAndDate(const char* locale,
|
||||||
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
|
||||||
|
|
||||||
// Using the id derived from the local, get the currency data
|
// Using the id derived from the local, get the currency data
|
||||||
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
|
UResourceBundle *countryArray = ures_getByKey(rb, id.data(), cm, &localStatus);
|
||||||
|
|
||||||
// process each currency to see which one is valid for the given date
|
// process each currency to see which one is valid for the given date
|
||||||
bool matchFound = false;
|
bool matchFound = false;
|
||||||
|
@ -2587,8 +2559,7 @@ static const UEnumeration defaultKeywordValues = {
|
||||||
|
|
||||||
U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, const char *locale, UBool commonlyUsed, UErrorCode* status) {
|
U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, const char *locale, UBool commonlyUsed, UErrorCode* status) {
|
||||||
// Resolve region
|
// Resolve region
|
||||||
char prefRegion[ULOC_COUNTRY_CAPACITY];
|
CharString prefRegion = ulocimp_getRegionForSupplementalData(locale, true, *status);
|
||||||
ulocimp_getRegionForSupplementalData(locale, true, prefRegion, sizeof(prefRegion), status);
|
|
||||||
|
|
||||||
// Read value from supplementalData
|
// Read value from supplementalData
|
||||||
UList *values = ulist_createEmptyList(status);
|
UList *values = ulist_createEmptyList(status);
|
||||||
|
@ -2621,7 +2592,7 @@ U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const char *region = ures_getKey(&bundlekey);
|
const char *region = ures_getKey(&bundlekey);
|
||||||
UBool isPrefRegion = uprv_strcmp(region, prefRegion) == 0 ? true : false;
|
UBool isPrefRegion = prefRegion == region;
|
||||||
if (!isPrefRegion && commonlyUsed) {
|
if (!isPrefRegion && commonlyUsed) {
|
||||||
// With commonlyUsed=true, we do not put
|
// With commonlyUsed=true, we do not put
|
||||||
// currencies for other regions in the
|
// currencies for other regions in the
|
||||||
|
@ -2732,7 +2703,7 @@ ucurr_getNumericCode(const char16_t* currency) {
|
||||||
if (currency && u_strlen(currency) == ISO_CURRENCY_CODE_LENGTH) {
|
if (currency && u_strlen(currency) == ISO_CURRENCY_CODE_LENGTH) {
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
UResourceBundle *bundle = ures_openDirect(0, "currencyNumericCodes", &status);
|
UResourceBundle *bundle = ures_openDirect(nullptr, "currencyNumericCodes", &status);
|
||||||
ures_getByKey(bundle, "codeMap", bundle, &status);
|
ures_getByKey(bundle, "codeMap", bundle, &status);
|
||||||
if (U_SUCCESS(status)) {
|
if (U_SUCCESS(status)) {
|
||||||
char alphaCode[ISO_CURRENCY_CODE_LENGTH+1];
|
char alphaCode[ISO_CURRENCY_CODE_LENGTH+1];
|
||||||
|
|
|
@ -850,8 +850,8 @@ static UBool extendICUData(UErrorCode *pErr)
|
||||||
UDataMemory_init(©PData);
|
UDataMemory_init(©PData);
|
||||||
if(pData != nullptr) {
|
if(pData != nullptr) {
|
||||||
UDatamemory_assign(©PData, pData);
|
UDatamemory_assign(©PData, pData);
|
||||||
copyPData.map = 0; /* The mapping for this data is owned by the hash table */
|
copyPData.map = nullptr; /* The mapping for this data is owned by the hash table */
|
||||||
copyPData.mapAddr = 0; /* which will unmap it when ICU is shut down. */
|
copyPData.mapAddr = nullptr; /* which will unmap it when ICU is shut down. */
|
||||||
/* CommonICUData is also unmapped when ICU is shut down.*/
|
/* CommonICUData is also unmapped when ICU is shut down.*/
|
||||||
/* To avoid unmapping the data twice, zero out the map */
|
/* To avoid unmapping the data twice, zero out the map */
|
||||||
/* fields in the UDataMemory that we're assigning */
|
/* fields in the UDataMemory that we're assigning */
|
||||||
|
|
|
@ -441,7 +441,7 @@ udata_openSwapperForInputData(const void *data, int32_t length,
|
||||||
pHeader->info.sizeofUChar!=2
|
pHeader->info.sizeofUChar!=2
|
||||||
) {
|
) {
|
||||||
*pErrorCode=U_UNSUPPORTED_ERROR;
|
*pErrorCode=U_UNSUPPORTED_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inIsBigEndian=(UBool)pHeader->info.isBigEndian;
|
inIsBigEndian=(UBool)pHeader->info.isBigEndian;
|
||||||
|
@ -461,7 +461,7 @@ udata_openSwapperForInputData(const void *data, int32_t length,
|
||||||
(length>=0 && length<headerSize)
|
(length>=0 && length<headerSize)
|
||||||
) {
|
) {
|
||||||
*pErrorCode=U_UNSUPPORTED_ERROR;
|
*pErrorCode=U_UNSUPPORTED_ERROR;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return udata_openSwapper(inIsBigEndian, inCharset, outIsBigEndian, outCharset, pErrorCode);
|
return udata_openSwapper(inIsBigEndian, inCharset, outIsBigEndian, outCharset, pErrorCode);
|
||||||
|
|
|
@ -66,7 +66,7 @@ noopSetState(UCharIterator * /*iter*/, uint32_t /*state*/, UErrorCode *pErrorCod
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UCharIterator noopIterator={
|
static const UCharIterator noopIterator={
|
||||||
0, 0, 0, 0, 0, 0,
|
nullptr, 0, 0, 0, 0, 0,
|
||||||
noopGetIndex,
|
noopGetIndex,
|
||||||
noopMove,
|
noopMove,
|
||||||
noopHasNext,
|
noopHasNext,
|
||||||
|
@ -197,7 +197,7 @@ stringIteratorSetState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCo
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UCharIterator stringIterator={
|
static const UCharIterator stringIterator={
|
||||||
0, 0, 0, 0, 0, 0,
|
nullptr, 0, 0, 0, 0, 0,
|
||||||
stringIteratorGetIndex,
|
stringIteratorGetIndex,
|
||||||
stringIteratorMove,
|
stringIteratorMove,
|
||||||
stringIteratorHasNext,
|
stringIteratorHasNext,
|
||||||
|
@ -212,8 +212,8 @@ static const UCharIterator stringIterator={
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_CAPI void U_EXPORT2
|
||||||
uiter_setString(UCharIterator *iter, const char16_t *s, int32_t length) {
|
uiter_setString(UCharIterator *iter, const char16_t *s, int32_t length) {
|
||||||
if(iter!=0) {
|
if (iter != nullptr) {
|
||||||
if(s!=0 && length>=-1) {
|
if (s != nullptr && length >= -1) {
|
||||||
*iter=stringIterator;
|
*iter=stringIterator;
|
||||||
iter->context=s;
|
iter->context=s;
|
||||||
if(length>=0) {
|
if(length>=0) {
|
||||||
|
@ -283,7 +283,7 @@ utf16BEIteratorPrevious(UCharIterator *iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UCharIterator utf16BEIterator={
|
static const UCharIterator utf16BEIterator={
|
||||||
0, 0, 0, 0, 0, 0,
|
nullptr, 0, 0, 0, 0, 0,
|
||||||
stringIteratorGetIndex,
|
stringIteratorGetIndex,
|
||||||
stringIteratorMove,
|
stringIteratorMove,
|
||||||
stringIteratorHasNext,
|
stringIteratorHasNext,
|
||||||
|
@ -457,7 +457,7 @@ characterIteratorSetState(UCharIterator *iter, uint32_t state, UErrorCode *pErro
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UCharIterator characterIteratorWrapper={
|
static const UCharIterator characterIteratorWrapper={
|
||||||
0, 0, 0, 0, 0, 0,
|
nullptr, 0, 0, 0, 0, 0,
|
||||||
characterIteratorGetIndex,
|
characterIteratorGetIndex,
|
||||||
characterIteratorMove,
|
characterIteratorMove,
|
||||||
characterIteratorHasNext,
|
characterIteratorHasNext,
|
||||||
|
@ -472,8 +472,8 @@ static const UCharIterator characterIteratorWrapper={
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_CAPI void U_EXPORT2
|
||||||
uiter_setCharacterIterator(UCharIterator *iter, CharacterIterator *charIter) {
|
uiter_setCharacterIterator(UCharIterator *iter, CharacterIterator *charIter) {
|
||||||
if(iter!=0) {
|
if (iter != nullptr) {
|
||||||
if(charIter!=0) {
|
if (charIter != nullptr) {
|
||||||
*iter=characterIteratorWrapper;
|
*iter=characterIteratorWrapper;
|
||||||
iter->context=charIter;
|
iter->context=charIter;
|
||||||
} else {
|
} else {
|
||||||
|
@ -521,7 +521,7 @@ replaceableIteratorPrevious(UCharIterator *iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UCharIterator replaceableIterator={
|
static const UCharIterator replaceableIterator={
|
||||||
0, 0, 0, 0, 0, 0,
|
nullptr, 0, 0, 0, 0, 0,
|
||||||
stringIteratorGetIndex,
|
stringIteratorGetIndex,
|
||||||
stringIteratorMove,
|
stringIteratorMove,
|
||||||
stringIteratorHasNext,
|
stringIteratorHasNext,
|
||||||
|
@ -536,8 +536,8 @@ static const UCharIterator replaceableIterator={
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_CAPI void U_EXPORT2
|
||||||
uiter_setReplaceable(UCharIterator *iter, const Replaceable *rep) {
|
uiter_setReplaceable(UCharIterator *iter, const Replaceable *rep) {
|
||||||
if(iter!=0) {
|
if (iter != nullptr) {
|
||||||
if(rep!=0) {
|
if (rep != nullptr) {
|
||||||
*iter=replaceableIterator;
|
*iter=replaceableIterator;
|
||||||
iter->context=rep;
|
iter->context=rep;
|
||||||
iter->limit=iter->length=rep->length();
|
iter->limit=iter->length=rep->length();
|
||||||
|
@ -987,7 +987,7 @@ utf8IteratorSetState(UCharIterator *iter,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UCharIterator utf8Iterator={
|
static const UCharIterator utf8Iterator={
|
||||||
0, 0, 0, 0, 0, 0,
|
nullptr, 0, 0, 0, 0, 0,
|
||||||
utf8IteratorGetIndex,
|
utf8IteratorGetIndex,
|
||||||
utf8IteratorMove,
|
utf8IteratorMove,
|
||||||
utf8IteratorHasNext,
|
utf8IteratorHasNext,
|
||||||
|
@ -1002,8 +1002,8 @@ static const UCharIterator utf8Iterator={
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_CAPI void U_EXPORT2
|
||||||
uiter_setUTF8(UCharIterator *iter, const char *s, int32_t length) {
|
uiter_setUTF8(UCharIterator *iter, const char *s, int32_t length) {
|
||||||
if(iter!=0) {
|
if (iter != nullptr) {
|
||||||
if(s!=0 && length>=-1) {
|
if (s != nullptr && length >= -1) {
|
||||||
*iter=utf8Iterator;
|
*iter=utf8Iterator;
|
||||||
iter->context=s;
|
iter->context=s;
|
||||||
if(length>=0) {
|
if(length>=0) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -74,8 +74,9 @@ uloc_key_type_cleanup() {
|
||||||
|
|
||||||
U_CDECL_END
|
U_CDECL_END
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
static void U_CALLCONV
|
void U_CALLCONV
|
||||||
initFromResourceBundle(UErrorCode& sts) {
|
initFromResourceBundle(UErrorCode& sts) {
|
||||||
U_NAMESPACE_USE
|
U_NAMESPACE_USE
|
||||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KEY_TYPE, uloc_key_type_cleanup);
|
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KEY_TYPE, uloc_key_type_cleanup);
|
||||||
|
@ -141,7 +142,7 @@ initFromResourceBundle(UErrorCode& sts) {
|
||||||
bcpKeyId = bcpKeyIdBuf->data();
|
bcpKeyId = bcpKeyIdBuf->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool isTZ = uprv_strcmp(legacyKeyId, "timezone") == 0;
|
bool isTZ = uprv_strcmp(legacyKeyId, "timezone") == 0;
|
||||||
|
|
||||||
UHashtable* typeDataMap = uhash_open(uhash_hashIChars, uhash_compareIChars, nullptr, &sts);
|
UHashtable* typeDataMap = uhash_open(uhash_hashIChars, uhash_compareIChars, nullptr, &sts);
|
||||||
if (U_FAILURE(sts)) {
|
if (U_FAILURE(sts)) {
|
||||||
|
@ -351,7 +352,7 @@ initFromResourceBundle(UErrorCode& sts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool
|
bool
|
||||||
init() {
|
init() {
|
||||||
UErrorCode sts = U_ZERO_ERROR;
|
UErrorCode sts = U_ZERO_ERROR;
|
||||||
umtx_initOnce(gLocExtKeyMapInitOnce, &initFromResourceBundle, sts);
|
umtx_initOnce(gLocExtKeyMapInitOnce, &initFromResourceBundle, sts);
|
||||||
|
@ -361,7 +362,7 @@ init() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool
|
bool
|
||||||
isSpecialTypeCodepoints(const char* val) {
|
isSpecialTypeCodepoints(const char* val) {
|
||||||
int32_t subtagLen = 0;
|
int32_t subtagLen = 0;
|
||||||
const char* p = val;
|
const char* p = val;
|
||||||
|
@ -383,7 +384,7 @@ isSpecialTypeCodepoints(const char* val) {
|
||||||
return (subtagLen >= 4 && subtagLen <= 6);
|
return (subtagLen >= 4 && subtagLen <= 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool
|
bool
|
||||||
isSpecialTypeReorderCode(const char* val) {
|
isSpecialTypeReorderCode(const char* val) {
|
||||||
int32_t subtagLen = 0;
|
int32_t subtagLen = 0;
|
||||||
const char* p = val;
|
const char* p = val;
|
||||||
|
@ -403,7 +404,7 @@ isSpecialTypeReorderCode(const char* val) {
|
||||||
return (subtagLen >=3 && subtagLen <=8);
|
return (subtagLen >=3 && subtagLen <=8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UBool
|
bool
|
||||||
isSpecialTypeRgKeyValue(const char* val) {
|
isSpecialTypeRgKeyValue(const char* val) {
|
||||||
int32_t subtagLen = 0;
|
int32_t subtagLen = 0;
|
||||||
const char* p = val;
|
const char* p = val;
|
||||||
|
@ -419,7 +420,9 @@ isSpecialTypeRgKeyValue(const char* val) {
|
||||||
return (subtagLen == 6);
|
return (subtagLen == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CFUNC const char*
|
} // namespace
|
||||||
|
|
||||||
|
U_EXPORT const char*
|
||||||
ulocimp_toBcpKey(const char* key) {
|
ulocimp_toBcpKey(const char* key) {
|
||||||
if (!init()) {
|
if (!init()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -432,7 +435,7 @@ ulocimp_toBcpKey(const char* key) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toLegacyKey(const char* key) {
|
ulocimp_toLegacyKey(const char* key) {
|
||||||
if (!init()) {
|
if (!init()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -445,8 +448,8 @@ ulocimp_toLegacyKey(const char* key) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toBcpType(const char* key, const char* type, UBool* isKnownKey, UBool* isSpecialType) {
|
ulocimp_toBcpType(const char* key, const char* type, bool* isKnownKey, bool* isSpecialType) {
|
||||||
if (isKnownKey != nullptr) {
|
if (isKnownKey != nullptr) {
|
||||||
*isKnownKey = false;
|
*isKnownKey = false;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +471,7 @@ ulocimp_toBcpType(const char* key, const char* type, UBool* isKnownKey, UBool* i
|
||||||
return t->bcpId;
|
return t->bcpId;
|
||||||
}
|
}
|
||||||
if (keyData->specialTypes != SPECIALTYPE_NONE) {
|
if (keyData->specialTypes != SPECIALTYPE_NONE) {
|
||||||
UBool matched = false;
|
bool matched = false;
|
||||||
if (keyData->specialTypes & SPECIALTYPE_CODEPOINTS) {
|
if (keyData->specialTypes & SPECIALTYPE_CODEPOINTS) {
|
||||||
matched = isSpecialTypeCodepoints(type);
|
matched = isSpecialTypeCodepoints(type);
|
||||||
}
|
}
|
||||||
|
@ -490,8 +493,8 @@ ulocimp_toBcpType(const char* key, const char* type, UBool* isKnownKey, UBool* i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool* isSpecialType) {
|
ulocimp_toLegacyType(const char* key, const char* type, bool* isKnownKey, bool* isSpecialType) {
|
||||||
if (isKnownKey != nullptr) {
|
if (isKnownKey != nullptr) {
|
||||||
*isKnownKey = false;
|
*isKnownKey = false;
|
||||||
}
|
}
|
||||||
|
@ -513,7 +516,7 @@ ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool
|
||||||
return t->legacyId;
|
return t->legacyId;
|
||||||
}
|
}
|
||||||
if (keyData->specialTypes != SPECIALTYPE_NONE) {
|
if (keyData->specialTypes != SPECIALTYPE_NONE) {
|
||||||
UBool matched = false;
|
bool matched = false;
|
||||||
if (keyData->specialTypes & SPECIALTYPE_CODEPOINTS) {
|
if (keyData->specialTypes & SPECIALTYPE_CODEPOINTS) {
|
||||||
matched = isSpecialTypeCodepoints(type);
|
matched = isSpecialTypeCodepoints(type);
|
||||||
}
|
}
|
||||||
|
@ -533,4 +536,3 @@ ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,7 @@
|
||||||
// © 2023 and later: Unicode, Inc. and others.
|
// © 2023 and later: Unicode, Inc. and others.
|
||||||
// License & terms of use: http://www.unicode.org/copyright.html
|
// License & terms of use: http://www.unicode.org/copyright.html
|
||||||
//
|
//
|
||||||
|
#include "unicode/bytestream.h"
|
||||||
#include "unicode/errorcode.h"
|
#include "unicode/errorcode.h"
|
||||||
#include "unicode/stringpiece.h"
|
#include "unicode/stringpiece.h"
|
||||||
#include "unicode/utypes.h"
|
#include "unicode/utypes.h"
|
||||||
|
@ -8,9 +9,9 @@
|
||||||
#include "unicode/ulocale.h"
|
#include "unicode/ulocale.h"
|
||||||
#include "unicode/locid.h"
|
#include "unicode/locid.h"
|
||||||
|
|
||||||
|
#include "bytesinkutil.h"
|
||||||
#include "charstr.h"
|
#include "charstr.h"
|
||||||
#include "cmemory.h"
|
#include "cmemory.h"
|
||||||
#include "ustr_imp.h"
|
|
||||||
|
|
||||||
U_NAMESPACE_USE
|
U_NAMESPACE_USE
|
||||||
#define EXTERNAL(i) (reinterpret_cast<ULocale*>(i))
|
#define EXTERNAL(i) (reinterpret_cast<ULocale*>(i))
|
||||||
|
@ -19,15 +20,17 @@ U_NAMESPACE_USE
|
||||||
|
|
||||||
ULocale*
|
ULocale*
|
||||||
ulocale_openForLocaleID(const char* localeID, int32_t length, UErrorCode* err) {
|
ulocale_openForLocaleID(const char* localeID, int32_t length, UErrorCode* err) {
|
||||||
|
if (U_FAILURE(*err)) { return nullptr; }
|
||||||
CharString str(length < 0 ? StringPiece(localeID) : StringPiece(localeID, length), *err);
|
CharString str(length < 0 ? StringPiece(localeID) : StringPiece(localeID, length), *err);
|
||||||
if (U_FAILURE(*err)) return nullptr;
|
if (U_FAILURE(*err)) { return nullptr; }
|
||||||
return EXTERNAL(icu::Locale::createFromName(str.data()).clone());
|
return EXTERNAL(icu::Locale::createFromName(str.data()).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
ULocale*
|
ULocale*
|
||||||
ulocale_openForLanguageTag(const char* tag, int32_t length, UErrorCode* err) {
|
ulocale_openForLanguageTag(const char* tag, int32_t length, UErrorCode* err) {
|
||||||
|
if (U_FAILURE(*err)) { return nullptr; }
|
||||||
Locale l = icu::Locale::forLanguageTag(length < 0 ? StringPiece(tag) : StringPiece(tag, length), *err);
|
Locale l = icu::Locale::forLanguageTag(length < 0 ? StringPiece(tag) : StringPiece(tag, length), *err);
|
||||||
if (U_FAILURE(*err)) return nullptr;
|
if (U_FAILURE(*err)) { return nullptr; }
|
||||||
return EXTERNAL(l.clone());
|
return EXTERNAL(l.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,20 +56,14 @@ int32_t ulocale_get ##N ( \
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR; \
|
*err = U_ILLEGAL_ARGUMENT_ERROR; \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
CheckedArrayByteSink sink(valueBuffer, bufferCapacity); \
|
return ByteSinkUtil::viaByteSinkToTerminatedChars( \
|
||||||
|
valueBuffer, bufferCapacity, \
|
||||||
|
[&](ByteSink& sink, UErrorCode& status) { \
|
||||||
CONST_INTERNAL(locale)->get ## N( \
|
CONST_INTERNAL(locale)->get ## N( \
|
||||||
keywordLength < 0 ? StringPiece(keyword) : StringPiece(keyword, keywordLength), \
|
keywordLength < 0 ? StringPiece(keyword) : StringPiece(keyword, keywordLength), \
|
||||||
sink, *err); \
|
sink, status); \
|
||||||
int32_t reslen = sink.NumberOfBytesAppended(); \
|
}, \
|
||||||
if (U_FAILURE(*err)) { \
|
*err); \
|
||||||
return reslen; \
|
|
||||||
} \
|
|
||||||
if (sink.Overflowed()) { \
|
|
||||||
*err = U_BUFFER_OVERFLOW_ERROR; \
|
|
||||||
} else { \
|
|
||||||
u_terminateChars(valueBuffer, bufferCapacity, reslen, err); \
|
|
||||||
} \
|
|
||||||
return reslen; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IMPL_ULOCALE_GET_KEYWORDS(N) \
|
#define IMPL_ULOCALE_GET_KEYWORDS(N) \
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include "unicode/stringpiece.h"
|
#include "unicode/stringpiece.h"
|
||||||
#include "unicode/umachine.h"
|
#include "unicode/umachine.h"
|
||||||
#include "unicode/ulocbuilder.h"
|
#include "unicode/ulocbuilder.h"
|
||||||
|
#include "bytesinkutil.h"
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
#include "ustr_imp.h"
|
#include "ustr_imp.h"
|
||||||
|
|
||||||
using icu::CheckedArrayByteSink;
|
|
||||||
using icu::StringPiece;
|
using icu::StringPiece;
|
||||||
|
|
||||||
#define EXTERNAL(i) (reinterpret_cast<ULocaleBuilder*>(i))
|
#define EXTERNAL(i) (reinterpret_cast<ULocaleBuilder*>(i))
|
||||||
|
@ -112,12 +112,13 @@ ULocale* ulocbld_buildULocale(ULocaleBuilder* builder, UErrorCode* err) {
|
||||||
|
|
||||||
int32_t ulocbld_buildLocaleID(ULocaleBuilder* builder,
|
int32_t ulocbld_buildLocaleID(ULocaleBuilder* builder,
|
||||||
char* buffer, int32_t bufferCapacity, UErrorCode* err) {
|
char* buffer, int32_t bufferCapacity, UErrorCode* err) {
|
||||||
|
if (U_FAILURE(*err)) { return 0; }
|
||||||
if (builder == nullptr) {
|
if (builder == nullptr) {
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
icu::Locale l = INTERNAL(builder)->build(*err);
|
icu::Locale l = INTERNAL(builder)->build(*err);
|
||||||
if (U_FAILURE(*err)) return 0;
|
if (U_FAILURE(*err)) { return 0; }
|
||||||
int32_t length = (int32_t)(uprv_strlen(l.getName()));
|
int32_t length = (int32_t)(uprv_strlen(l.getName()));
|
||||||
if (0 < length && length <= bufferCapacity) {
|
if (0 < length && length <= bufferCapacity) {
|
||||||
uprv_memcpy(buffer, l.getName(), length);
|
uprv_memcpy(buffer, l.getName(), length);
|
||||||
|
@ -127,24 +128,18 @@ int32_t ulocbld_buildLocaleID(ULocaleBuilder* builder,
|
||||||
|
|
||||||
int32_t ulocbld_buildLanguageTag(ULocaleBuilder* builder,
|
int32_t ulocbld_buildLanguageTag(ULocaleBuilder* builder,
|
||||||
char* buffer, int32_t bufferCapacity, UErrorCode* err) {
|
char* buffer, int32_t bufferCapacity, UErrorCode* err) {
|
||||||
|
if (U_FAILURE(*err)) { return 0; }
|
||||||
if (builder == nullptr) {
|
if (builder == nullptr) {
|
||||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
icu::Locale l = INTERNAL(builder)->build(*err);
|
icu::Locale l = INTERNAL(builder)->build(*err);
|
||||||
if (U_FAILURE(*err)) return 0;
|
return icu::ByteSinkUtil::viaByteSinkToTerminatedChars(
|
||||||
CheckedArrayByteSink sink(buffer, bufferCapacity);
|
buffer, bufferCapacity,
|
||||||
l.toLanguageTag(sink, *err);
|
[&](icu::ByteSink& sink, UErrorCode& status) {
|
||||||
int32_t reslen = sink.NumberOfBytesAppended();
|
l.toLanguageTag(sink, status);
|
||||||
if (U_FAILURE(*err)) {
|
},
|
||||||
return reslen;
|
*err);
|
||||||
}
|
|
||||||
if (sink.Overflowed()) {
|
|
||||||
*err = U_BUFFER_OVERFLOW_ERROR;
|
|
||||||
} else {
|
|
||||||
u_terminateChars(buffer, bufferCapacity, reslen, err);
|
|
||||||
}
|
|
||||||
return reslen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool ulocbld_copyErrorTo(const ULocaleBuilder* builder, UErrorCode *outErrorCode) {
|
UBool ulocbld_copyErrorTo(const ULocaleBuilder* builder, UErrorCode *outErrorCode) {
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef ULOCIMP_H
|
#ifndef ULOCIMP_H
|
||||||
#define ULOCIMP_H
|
#define ULOCIMP_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include "unicode/bytestream.h"
|
#include "unicode/bytestream.h"
|
||||||
#include "unicode/uloc.h"
|
#include "unicode/uloc.h"
|
||||||
|
|
||||||
|
@ -40,8 +42,10 @@ uloc_getTableStringWithFallback(
|
||||||
int32_t *pLength,
|
int32_t *pLength,
|
||||||
UErrorCode *pErrorCode);
|
UErrorCode *pErrorCode);
|
||||||
|
|
||||||
|
namespace {
|
||||||
/*returns true if a is an ID separator false otherwise*/
|
/*returns true if a is an ID separator false otherwise*/
|
||||||
#define _isIDSeparator(a) (a == '_' || a == '-')
|
inline bool _isIDSeparator(char a) { return a == '_' || a == '-'; }
|
||||||
|
} // namespace
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_CFUNC const char*
|
||||||
uloc_getCurrentCountryID(const char* oldID);
|
uloc_getCurrentCountryID(const char* oldID);
|
||||||
|
@ -49,53 +53,134 @@ uloc_getCurrentCountryID(const char* oldID);
|
||||||
U_CFUNC const char*
|
U_CFUNC const char*
|
||||||
uloc_getCurrentLanguageID(const char* oldID);
|
uloc_getCurrentLanguageID(const char* oldID);
|
||||||
|
|
||||||
U_CFUNC void
|
U_EXPORT icu::CharString
|
||||||
ulocimp_getKeywords(const char *localeID,
|
ulocimp_getKeywords(const char* localeID,
|
||||||
|
char prev,
|
||||||
|
bool valuesToo,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
|
ulocimp_getKeywords(const char* localeID,
|
||||||
char prev,
|
char prev,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UBool valuesToo,
|
bool valuesToo,
|
||||||
UErrorCode *status);
|
UErrorCode& status);
|
||||||
|
|
||||||
icu::CharString U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
ulocimp_getLanguage(const char *localeID,
|
ulocimp_getName(const char* localeID,
|
||||||
const char **pEnd,
|
UErrorCode& err);
|
||||||
UErrorCode &status);
|
|
||||||
|
|
||||||
icu::CharString U_EXPORT2
|
U_EXPORT void
|
||||||
ulocimp_getScript(const char *localeID,
|
|
||||||
const char **pEnd,
|
|
||||||
UErrorCode &status);
|
|
||||||
|
|
||||||
icu::CharString U_EXPORT2
|
|
||||||
ulocimp_getCountry(const char *localeID,
|
|
||||||
const char **pEnd,
|
|
||||||
UErrorCode &status);
|
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
|
||||||
ulocimp_getName(const char* localeID,
|
ulocimp_getName(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getBaseName(const char* localeID,
|
||||||
|
UErrorCode& err);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
ulocimp_getBaseName(const char* localeID,
|
ulocimp_getBaseName(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_canonicalize(const char* localeID,
|
||||||
|
UErrorCode& err);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
ulocimp_canonicalize(const char* localeID,
|
ulocimp_canonicalize(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getKeywordValue(const char* localeID,
|
||||||
|
const char* keywordName,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
ulocimp_getKeywordValue(const char* localeID,
|
ulocimp_getKeywordValue(const char* localeID,
|
||||||
const char* keywordName,
|
const char* keywordName,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* status);
|
UErrorCode& status);
|
||||||
|
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getLanguage(const char* localeID, UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getScript(const char* localeID, UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getRegion(const char* localeID, UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getVariant(const char* localeID, UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
|
ulocimp_setKeywordValue(const char* keywordName,
|
||||||
|
const char* keywordValue,
|
||||||
|
icu::CharString& localeID,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT int32_t
|
||||||
|
ulocimp_setKeywordValue(const char* keywords,
|
||||||
|
const char* keywordName,
|
||||||
|
const char* keywordValue,
|
||||||
|
icu::ByteSink& sink,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
|
ulocimp_getSubtags(
|
||||||
|
const char* localeID,
|
||||||
|
icu::CharString* language,
|
||||||
|
icu::CharString* script,
|
||||||
|
icu::CharString* region,
|
||||||
|
icu::CharString* variant,
|
||||||
|
const char** pEnd,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
|
ulocimp_getSubtags(
|
||||||
|
const char* localeID,
|
||||||
|
icu::ByteSink* language,
|
||||||
|
icu::ByteSink* script,
|
||||||
|
icu::ByteSink* region,
|
||||||
|
icu::ByteSink* variant,
|
||||||
|
const char** pEnd,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ulocimp_getSubtags(
|
||||||
|
const char* localeID,
|
||||||
|
std::nullptr_t,
|
||||||
|
std::nullptr_t,
|
||||||
|
std::nullptr_t,
|
||||||
|
std::nullptr_t,
|
||||||
|
const char** pEnd,
|
||||||
|
UErrorCode& status) {
|
||||||
|
ulocimp_getSubtags(
|
||||||
|
localeID,
|
||||||
|
static_cast<icu::ByteSink*>(nullptr),
|
||||||
|
static_cast<icu::ByteSink*>(nullptr),
|
||||||
|
static_cast<icu::ByteSink*>(nullptr),
|
||||||
|
static_cast<icu::ByteSink*>(nullptr),
|
||||||
|
pEnd,
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_getParent(const char* localeID,
|
||||||
|
UErrorCode& err);
|
||||||
|
|
||||||
|
U_EXPORT void
|
||||||
ulocimp_getParent(const char* localeID,
|
ulocimp_getParent(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_toLanguageTag(const char* localeID,
|
||||||
|
bool strict,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a well-formed language tag for this locale ID.
|
* Writes a well-formed language tag for this locale ID.
|
||||||
|
@ -116,11 +201,17 @@ ulocimp_getParent(const char* localeID,
|
||||||
*
|
*
|
||||||
* @internal ICU 64
|
* @internal ICU 64
|
||||||
*/
|
*/
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT void
|
||||||
ulocimp_toLanguageTag(const char* localeID,
|
ulocimp_toLanguageTag(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UBool strict,
|
bool strict,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_forLanguageTag(const char* langtag,
|
||||||
|
int32_t tagLen,
|
||||||
|
int32_t* parsedLength,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a locale ID for the specified BCP47 language tag string.
|
* Returns a locale ID for the specified BCP47 language tag string.
|
||||||
|
@ -148,12 +239,12 @@ ulocimp_toLanguageTag(const char* localeID,
|
||||||
* failed.
|
* failed.
|
||||||
* @internal ICU 63
|
* @internal ICU 63
|
||||||
*/
|
*/
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT void
|
||||||
ulocimp_forLanguageTag(const char* langtag,
|
ulocimp_forLanguageTag(const char* langtag,
|
||||||
int32_t tagLen,
|
int32_t tagLen,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
int32_t* parsedLength,
|
int32_t* parsedLength,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the region to use for supplemental data lookup. Uses
|
* Get the region to use for supplemental data lookup. Uses
|
||||||
|
@ -161,7 +252,7 @@ ulocimp_forLanguageTag(const char* langtag,
|
||||||
* (2) any unicode_region_tag in the locale ID; if none then
|
* (2) any unicode_region_tag in the locale ID; if none then
|
||||||
* (3) if inferRegion is true, the region suggested by
|
* (3) if inferRegion is true, the region suggested by
|
||||||
* getLikelySubtags on the localeID.
|
* getLikelySubtags on the localeID.
|
||||||
* If no region is found, returns length 0.
|
* If no region is found, returns an empty string.
|
||||||
*
|
*
|
||||||
* @param localeID
|
* @param localeID
|
||||||
* The complete locale ID (with keywords) from which
|
* The complete locale ID (with keywords) from which
|
||||||
|
@ -169,20 +260,19 @@ ulocimp_forLanguageTag(const char* langtag,
|
||||||
* @param inferRegion
|
* @param inferRegion
|
||||||
* If true, will try to infer region from localeID if
|
* If true, will try to infer region from localeID if
|
||||||
* no other region is found.
|
* no other region is found.
|
||||||
* @param region
|
|
||||||
* Buffer in which to put the region ID found; should
|
|
||||||
* have a capacity at least ULOC_COUNTRY_CAPACITY.
|
|
||||||
* @param regionCapacity
|
|
||||||
* The actual capacity of the region buffer.
|
|
||||||
* @param status
|
* @param status
|
||||||
* Pointer to in/out UErrorCode value for latest status.
|
* Pointer to in/out UErrorCode value for latest status.
|
||||||
* @return
|
* @return
|
||||||
* The length of any region code found, or 0 if none.
|
* The region code found, empty if none found.
|
||||||
* @internal ICU 57
|
* @internal ICU 57
|
||||||
*/
|
*/
|
||||||
U_CAPI int32_t U_EXPORT2
|
U_EXPORT icu::CharString
|
||||||
ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
|
ulocimp_getRegionForSupplementalData(const char *localeID, bool inferRegion,
|
||||||
char *region, int32_t regionCapacity, UErrorCode* status);
|
UErrorCode& status);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_addLikelySubtags(const char* localeID,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the likely subtags for a provided locale ID, per the algorithm described
|
* Add the likely subtags for a provided locale ID, per the algorithm described
|
||||||
|
@ -213,10 +303,15 @@ ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
|
||||||
* or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR.
|
* or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR.
|
||||||
* @internal ICU 64
|
* @internal ICU 64
|
||||||
*/
|
*/
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT void
|
||||||
ulocimp_addLikelySubtags(const char* localeID,
|
ulocimp_addLikelySubtags(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
|
U_EXPORT icu::CharString
|
||||||
|
ulocimp_minimizeSubtags(const char* localeID,
|
||||||
|
bool favorScript,
|
||||||
|
UErrorCode& status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimize the subtags for a provided locale ID, per the algorithm described
|
* Minimize the subtags for a provided locale ID, per the algorithm described
|
||||||
|
@ -248,70 +343,72 @@ ulocimp_addLikelySubtags(const char* localeID,
|
||||||
* or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR.
|
* or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR.
|
||||||
* @internal ICU 64
|
* @internal ICU 64
|
||||||
*/
|
*/
|
||||||
U_CAPI void U_EXPORT2
|
U_EXPORT void
|
||||||
ulocimp_minimizeSubtags(const char* localeID,
|
ulocimp_minimizeSubtags(const char* localeID,
|
||||||
icu::ByteSink& sink,
|
icu::ByteSink& sink,
|
||||||
bool favorScript,
|
bool favorScript,
|
||||||
UErrorCode* err);
|
UErrorCode& err);
|
||||||
|
|
||||||
U_CAPI const char * U_EXPORT2
|
U_CAPI const char * U_EXPORT2
|
||||||
locale_getKeywordsStart(const char *localeID);
|
locale_getKeywordsStart(const char *localeID);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isExtensionSubtags(const char* s, int32_t len);
|
ultag_isExtensionSubtags(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isLanguageSubtag(const char* s, int32_t len);
|
ultag_isLanguageSubtag(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isPrivateuseValueSubtags(const char* s, int32_t len);
|
ultag_isPrivateuseValueSubtags(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isRegionSubtag(const char* s, int32_t len);
|
ultag_isRegionSubtag(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isScriptSubtag(const char* s, int32_t len);
|
ultag_isScriptSubtag(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isTransformedExtensionSubtags(const char* s, int32_t len);
|
ultag_isTransformedExtensionSubtags(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isUnicodeExtensionSubtags(const char* s, int32_t len);
|
ultag_isUnicodeExtensionSubtags(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isUnicodeLocaleAttribute(const char* s, int32_t len);
|
ultag_isUnicodeLocaleAttribute(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isUnicodeLocaleAttributes(const char* s, int32_t len);
|
ultag_isUnicodeLocaleAttributes(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isUnicodeLocaleKey(const char* s, int32_t len);
|
ultag_isUnicodeLocaleKey(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isUnicodeLocaleType(const char* s, int32_t len);
|
ultag_isUnicodeLocaleType(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CFUNC UBool
|
bool
|
||||||
ultag_isVariantSubtags(const char* s, int32_t len);
|
ultag_isVariantSubtags(const char* s, int32_t len);
|
||||||
|
|
||||||
U_CAPI const char * U_EXPORT2
|
const char*
|
||||||
ultag_getTKeyStart(const char *localeID);
|
ultag_getTKeyStart(const char* localeID);
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toBcpKey(const char* key);
|
ulocimp_toBcpKey(const char* key);
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toLegacyKey(const char* key);
|
ulocimp_toLegacyKey(const char* key);
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toBcpType(const char* key, const char* type, UBool* isKnownKey, UBool* isSpecialType);
|
ulocimp_toBcpType(const char* key, const char* type, bool* isKnownKey, bool* isSpecialType);
|
||||||
|
|
||||||
U_CFUNC const char*
|
U_EXPORT const char*
|
||||||
ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool* isSpecialType);
|
ulocimp_toLegacyType(const char* key, const char* type, bool* isKnownKey, bool* isSpecialType);
|
||||||
|
|
||||||
/* Function for testing purpose */
|
/* Function for testing purpose */
|
||||||
U_CAPI const char* const* ulocimp_getKnownCanonicalizedLocaleForTest(int32_t* length);
|
U_EXPORT const char* const*
|
||||||
|
ulocimp_getKnownCanonicalizedLocaleForTest(int32_t& length);
|
||||||
|
|
||||||
// Return true if the value is already canonicalized.
|
// Return true if the value is already canonicalized.
|
||||||
U_CAPI bool ulocimp_isCanonicalizedLocaleForTest(const char* localeName);
|
U_EXPORT bool
|
||||||
|
ulocimp_isCanonicalizedLocaleForTest(const char* localeName);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -236,9 +236,9 @@ typedef HANDLE MemoryMap;
|
||||||
|
|
||||||
/* get a view of the mapping */
|
/* get a view of the mapping */
|
||||||
#if U_PLATFORM != U_PF_HPUX
|
#if U_PLATFORM != U_PF_HPUX
|
||||||
data=mmap(0, length, PROT_READ, MAP_SHARED, fd, 0);
|
data=mmap(nullptr, length, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
#else
|
#else
|
||||||
data=mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
|
data=mmap(nullptr, length, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
#endif
|
#endif
|
||||||
close(fd); /* no longer needed */
|
close(fd); /* no longer needed */
|
||||||
if(data==MAP_FAILED) {
|
if(data==MAP_FAILED) {
|
||||||
|
@ -262,7 +262,7 @@ typedef HANDLE MemoryMap;
|
||||||
if(munmap(pData->mapAddr, dataLen)==-1) {
|
if(munmap(pData->mapAddr, dataLen)==-1) {
|
||||||
}
|
}
|
||||||
pData->pHeader=nullptr;
|
pData->pHeader=nullptr;
|
||||||
pData->map=0;
|
pData->map=nullptr;
|
||||||
pData->mapAddr=nullptr;
|
pData->mapAddr=nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,6 @@ u_setMutexFunctions(const void * /*context */, UMtxInitFn *, UMtxFn *,
|
||||||
if (U_SUCCESS(*status)) {
|
if (U_SUCCESS(*status)) {
|
||||||
*status = U_UNSUPPORTED_ERROR;
|
*status = U_UNSUPPORTED_ERROR;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,5 +199,4 @@ u_setAtomicIncDecFunctions(const void * /*context */, UMtxAtomicFn *, UMtxAtomic
|
||||||
if (U_SUCCESS(*status)) {
|
if (U_SUCCESS(*status)) {
|
||||||
*status = U_UNSUPPORTED_ERROR;
|
*status = U_UNSUPPORTED_ERROR;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,14 +146,13 @@ public:
|
||||||
* will return distinct unequal values.
|
* will return distinct unequal values.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override = 0;
|
virtual UClassID getDynamicClassID() const override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a CharacterIterator over the text being analyzed.
|
* Return a CharacterIterator over the text being analyzed.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual CharacterIterator& getText(void) const = 0;
|
virtual CharacterIterator& getText() const = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a UText for the text being analyzed.
|
* Get a UText for the text being analyzed.
|
||||||
|
@ -228,14 +227,14 @@ public:
|
||||||
* @return The offset of the beginning of the text, zero.
|
* @return The offset of the beginning of the text, zero.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t first(void) = 0;
|
virtual int32_t first() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the iterator position to the index immediately BEYOND the last character in the text being scanned.
|
* Set the iterator position to the index immediately BEYOND the last character in the text being scanned.
|
||||||
* @return The index immediately BEYOND the last character in the text being scanned.
|
* @return The index immediately BEYOND the last character in the text being scanned.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t last(void) = 0;
|
virtual int32_t last() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the iterator position to the boundary preceding the current boundary.
|
* Set the iterator position to the boundary preceding the current boundary.
|
||||||
|
@ -243,7 +242,7 @@ public:
|
||||||
* boundaries have been returned.
|
* boundaries have been returned.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t previous(void) = 0;
|
virtual int32_t previous() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advance the iterator to the boundary following the current boundary.
|
* Advance the iterator to the boundary following the current boundary.
|
||||||
|
@ -251,14 +250,14 @@ public:
|
||||||
* boundaries have been returned.
|
* boundaries have been returned.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t next(void) = 0;
|
virtual int32_t next() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return character index of the current iterator position within the text.
|
* Return character index of the current iterator position within the text.
|
||||||
* @return The boundary most recently returned.
|
* @return The boundary most recently returned.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t current(void) const = 0;
|
virtual int32_t current() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advance the iterator to the first boundary following the specified offset.
|
* Advance the iterator to the first boundary following the specified offset.
|
||||||
|
@ -530,7 +529,7 @@ public:
|
||||||
* must be closed by an explicit call to the destructor (not delete).
|
* must be closed by an explicit call to the destructor (not delete).
|
||||||
* @deprecated ICU 52. Always delete the BreakIterator.
|
* @deprecated ICU 52. Always delete the BreakIterator.
|
||||||
*/
|
*/
|
||||||
inline UBool isBufferClone(void);
|
inline UBool isBufferClone();
|
||||||
|
|
||||||
#endif /* U_HIDE_DEPRECATED_API */
|
#endif /* U_HIDE_DEPRECATED_API */
|
||||||
|
|
||||||
|
@ -575,7 +574,7 @@ public:
|
||||||
* @return a StringEnumeration over the locales available at the time of the call
|
* @return a StringEnumeration over the locales available at the time of the call
|
||||||
* @stable ICU 2.4
|
* @stable ICU 2.4
|
||||||
*/
|
*/
|
||||||
static StringEnumeration* U_EXPORT2 getAvailableLocales(void);
|
static StringEnumeration* U_EXPORT2 getAvailableLocales();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -128,9 +128,10 @@ public:
|
||||||
* @param skipZeros determine if skip zeros
|
* @param skipZeros determine if skip zeros
|
||||||
* @param result the results in a set.
|
* @param result the results in a set.
|
||||||
* @param status Fill-in parameter which receives the status of this operation.
|
* @param status Fill-in parameter which receives the status of this operation.
|
||||||
|
* @param depth depth of the call.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
static void U_EXPORT2 permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status);
|
static void U_EXPORT2 permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status, int32_t depth=0);
|
||||||
#endif /* U_HIDE_INTERNAL_API */
|
#endif /* U_HIDE_INTERNAL_API */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,8 +183,8 @@ private:
|
||||||
// transient fields
|
// transient fields
|
||||||
UnicodeString buffer;
|
UnicodeString buffer;
|
||||||
|
|
||||||
const Normalizer2 &nfd;
|
const Normalizer2 *nfd;
|
||||||
const Normalizer2Impl &nfcImpl;
|
const Normalizer2Impl *nfcImpl;
|
||||||
|
|
||||||
// we have a segment, in NFD. Find all the strings that are canonically equivalent to it.
|
// we have a segment, in NFD. Find all the strings that are canonically equivalent to it.
|
||||||
UnicodeString *getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status); //private String[] getEquivalents(String segment)
|
UnicodeString *getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status); //private String[] getEquivalents(String segment)
|
||||||
|
|
|
@ -133,7 +133,7 @@ public:
|
||||||
* @return the hash code.
|
* @return the hash code.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t hashCode(void) const = 0;
|
virtual int32_t hashCode() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a UClassID for this ForwardCharacterIterator ("poor man's
|
* Returns a UClassID for this ForwardCharacterIterator ("poor man's
|
||||||
|
@ -142,7 +142,7 @@ public:
|
||||||
* @return a UClassID for this ForwardCharacterIterator
|
* @return a UClassID for this ForwardCharacterIterator
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override = 0;
|
virtual UClassID getDynamicClassID() const override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current code unit for returning and advances to the next code unit
|
* Gets the current code unit for returning and advances to the next code unit
|
||||||
|
@ -152,7 +152,7 @@ public:
|
||||||
* @return the current code unit.
|
* @return the current code unit.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t nextPostInc(void) = 0;
|
virtual char16_t nextPostInc() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current code point for returning and advances to the next code point
|
* Gets the current code point for returning and advances to the next code point
|
||||||
|
@ -162,7 +162,7 @@ public:
|
||||||
* @return the current code point.
|
* @return the current code point.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 next32PostInc(void) = 0;
|
virtual UChar32 next32PostInc() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns false if there are no more code units or code points
|
* Returns false if there are no more code units or code points
|
||||||
|
@ -389,7 +389,7 @@ public:
|
||||||
* @return the first code unit in its iteration range.
|
* @return the first code unit in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t first(void) = 0;
|
virtual char16_t first() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code unit in its
|
* Sets the iterator to refer to the first code unit in its
|
||||||
|
@ -399,7 +399,7 @@ public:
|
||||||
* @return the first code unit in its iteration range.
|
* @return the first code unit in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t firstPostInc(void);
|
virtual char16_t firstPostInc();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code point in its
|
* Sets the iterator to refer to the first code point in its
|
||||||
|
@ -410,7 +410,7 @@ public:
|
||||||
* @return the first code point in its iteration range.
|
* @return the first code point in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 first32(void) = 0;
|
virtual UChar32 first32() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code point in its
|
* Sets the iterator to refer to the first code point in its
|
||||||
|
@ -420,7 +420,7 @@ public:
|
||||||
* @return the first code point in its iteration range.
|
* @return the first code point in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 first32PostInc(void);
|
virtual UChar32 first32PostInc();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code unit or code point in its
|
* Sets the iterator to refer to the first code unit or code point in its
|
||||||
|
@ -438,7 +438,7 @@ public:
|
||||||
* @return the last code unit.
|
* @return the last code unit.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t last(void) = 0;
|
virtual char16_t last() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the last code point in its
|
* Sets the iterator to refer to the last code point in its
|
||||||
|
@ -447,7 +447,7 @@ public:
|
||||||
* @return the last code point.
|
* @return the last code point.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 last32(void) = 0;
|
virtual UChar32 last32() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to the end of its iteration range, just behind
|
* Sets the iterator to the end of its iteration range, just behind
|
||||||
|
@ -486,14 +486,14 @@ public:
|
||||||
* @return the current code unit.
|
* @return the current code unit.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t current(void) const = 0;
|
virtual char16_t current() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the code point the iterator currently refers to.
|
* Returns the code point the iterator currently refers to.
|
||||||
* @return the current code point.
|
* @return the current code point.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 current32(void) const = 0;
|
virtual UChar32 current32() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the next code unit in the iteration range
|
* Advances to the next code unit in the iteration range
|
||||||
|
@ -502,7 +502,7 @@ public:
|
||||||
* @return the next code unit.
|
* @return the next code unit.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t next(void) = 0;
|
virtual char16_t next() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the next code point in the iteration range
|
* Advances to the next code point in the iteration range
|
||||||
|
@ -514,7 +514,7 @@ public:
|
||||||
* @return the next code point.
|
* @return the next code point.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 next32(void) = 0;
|
virtual UChar32 next32() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the previous code unit in the iteration range
|
* Advances to the previous code unit in the iteration range
|
||||||
|
@ -523,7 +523,7 @@ public:
|
||||||
* @return the previous code unit.
|
* @return the previous code unit.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t previous(void) = 0;
|
virtual char16_t previous() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the previous code point in the iteration range
|
* Advances to the previous code point in the iteration range
|
||||||
|
@ -532,7 +532,7 @@ public:
|
||||||
* @return the previous code point.
|
* @return the previous code point.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 previous32(void) = 0;
|
virtual UChar32 previous32() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns false if there are no more code units or code points
|
* Returns false if there are no more code units or code points
|
||||||
|
@ -555,7 +555,7 @@ public:
|
||||||
* object of the character returned by first().
|
* object of the character returned by first().
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t startIndex(void) const;
|
inline int32_t startIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the numeric index in the underlying text-storage
|
* Returns the numeric index in the underlying text-storage
|
||||||
|
@ -566,7 +566,7 @@ public:
|
||||||
* returned by last().
|
* returned by last().
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t endIndex(void) const;
|
inline int32_t endIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the numeric index in the underlying text-storage
|
* Returns the numeric index in the underlying text-storage
|
||||||
|
@ -576,7 +576,7 @@ public:
|
||||||
* the character the iterator currently refers to
|
* the character the iterator currently refers to
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t getIndex(void) const;
|
inline int32_t getIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the length of the entire text in the underlying
|
* Returns the length of the entire text in the underlying
|
||||||
|
@ -708,22 +708,22 @@ CharacterIterator::setToEnd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t
|
inline int32_t
|
||||||
CharacterIterator::startIndex(void) const {
|
CharacterIterator::startIndex() const {
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t
|
inline int32_t
|
||||||
CharacterIterator::endIndex(void) const {
|
CharacterIterator::endIndex() const {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t
|
inline int32_t
|
||||||
CharacterIterator::getIndex(void) const {
|
CharacterIterator::getIndex() const {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t
|
inline int32_t
|
||||||
CharacterIterator::getLength(void) const {
|
CharacterIterator::getLength() const {
|
||||||
return textLength;
|
return textLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,11 @@
|
||||||
* <td>icu::MessageFormat</td>
|
* <td>icu::MessageFormat</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
|
* <td>Message Formatting 2<br/>(technology preview)</td>
|
||||||
|
* <td>(no C API)</td>
|
||||||
|
* <td>icu::message2::MessageFormatter</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
* <td>List Formatting</td>
|
* <td>List Formatting</td>
|
||||||
* <td>ulistformatter.h</td>
|
* <td>ulistformatter.h</td>
|
||||||
* <td>icu::ListFormatter</td>
|
* <td>icu::ListFormatter</td>
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
* @return The class ID for all objects of this class.
|
* @return The class ID for all objects of this class.
|
||||||
* @stable ICU 4.0
|
* @stable ICU 4.0
|
||||||
*/
|
*/
|
||||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
static UClassID U_EXPORT2 getStaticClassID();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
|
* Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
|
||||||
|
@ -89,8 +89,7 @@ public:
|
||||||
* other classes have different class IDs.
|
* other classes have different class IDs.
|
||||||
* @stable ICU 4.0
|
* @stable ICU 4.0
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override;
|
virtual UClassID getDynamicClassID() const override;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy constructor.
|
* Copy constructor.
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#if U_SHOW_CPLUSPLUS_API
|
#if U_SHOW_CPLUSPLUS_API
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "unicode/locid.h"
|
#include "unicode/locid.h"
|
||||||
#include "unicode/stringpiece.h"
|
#include "unicode/stringpiece.h"
|
||||||
#include "unicode/uobject.h"
|
#include "unicode/uobject.h"
|
||||||
|
@ -133,10 +135,10 @@ U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct LSR;
|
struct LSR;
|
||||||
|
|
||||||
|
class LikelySubtags;
|
||||||
class LocaleDistance;
|
class LocaleDistance;
|
||||||
class LocaleLsrIterator;
|
class LocaleLsrIterator;
|
||||||
class UVector;
|
class UVector;
|
||||||
class XLikelySubtags;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable class that picks the best match between a user's desired locales and
|
* Immutable class that picks the best match between a user's desired locales and
|
||||||
|
@ -678,9 +680,9 @@ private:
|
||||||
|
|
||||||
int32_t putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength, UErrorCode &errorCode);
|
int32_t putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength, UErrorCode &errorCode);
|
||||||
|
|
||||||
int32_t getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
|
std::optional<int32_t> getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
|
||||||
|
|
||||||
const XLikelySubtags &likelySubtags;
|
const LikelySubtags &likelySubtags;
|
||||||
const LocaleDistance &localeDistance;
|
const LocaleDistance &localeDistance;
|
||||||
int32_t thresholdDistance;
|
int32_t thresholdDistance;
|
||||||
int32_t demotionPerDesiredLocale;
|
int32_t demotionPerDesiredLocale;
|
||||||
|
|
|
@ -162,11 +162,11 @@ protected:
|
||||||
T *ptr;
|
T *ptr;
|
||||||
private:
|
private:
|
||||||
// No comparison operators with other LocalPointerBases.
|
// No comparison operators with other LocalPointerBases.
|
||||||
bool operator==(const LocalPointerBase<T> &other);
|
bool operator==(const LocalPointerBase<T> &other) = delete;
|
||||||
bool operator!=(const LocalPointerBase<T> &other);
|
bool operator!=(const LocalPointerBase<T> &other) = delete;
|
||||||
// No ownership sharing: No copy constructor, no assignment operator.
|
// No ownership sharing: No copy constructor, no assignment operator.
|
||||||
LocalPointerBase(const LocalPointerBase<T> &other);
|
LocalPointerBase(const LocalPointerBase<T> &other) = delete;
|
||||||
void operator=(const LocalPointerBase<T> &other);
|
void operator=(const LocalPointerBase<T> &other) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -548,46 +548,60 @@ public:
|
||||||
* @stable ICU 4.4
|
* @stable ICU 4.4
|
||||||
*/
|
*/
|
||||||
#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
|
#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
|
||||||
class LocalPointerClassName : public LocalPointerBase<Type> { \
|
using LocalPointerClassName = internal::LocalOpenPointer<Type, closeFunction>
|
||||||
public: \
|
|
||||||
using LocalPointerBase<Type>::operator*; \
|
#ifndef U_IN_DOXYGEN
|
||||||
using LocalPointerBase<Type>::operator->; \
|
namespace internal {
|
||||||
explicit LocalPointerClassName(Type *p=nullptr) : LocalPointerBase<Type>(p) {} \
|
/**
|
||||||
LocalPointerClassName(LocalPointerClassName &&src) noexcept \
|
* Implementation, do not use directly: use U_DEFINE_LOCAL_OPEN_POINTER.
|
||||||
: LocalPointerBase<Type>(src.ptr) { \
|
*
|
||||||
src.ptr=nullptr; \
|
* @see U_DEFINE_LOCAL_OPEN_POINTER
|
||||||
} \
|
* @internal
|
||||||
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
|
*/
|
||||||
explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \
|
template <typename Type, auto closeFunction>
|
||||||
: LocalPointerBase<Type>(p.release()) {} \
|
class LocalOpenPointer : public LocalPointerBase<Type> {
|
||||||
~LocalPointerClassName() { if (ptr != nullptr) { closeFunction(ptr); } } \
|
using LocalPointerBase<Type>::ptr;
|
||||||
LocalPointerClassName &operator=(LocalPointerClassName &&src) noexcept { \
|
public:
|
||||||
if (ptr != nullptr) { closeFunction(ptr); } \
|
using LocalPointerBase<Type>::operator*;
|
||||||
LocalPointerBase<Type>::ptr=src.ptr; \
|
using LocalPointerBase<Type>::operator->;
|
||||||
src.ptr=nullptr; \
|
explicit LocalOpenPointer(Type *p=nullptr) : LocalPointerBase<Type>(p) {}
|
||||||
return *this; \
|
LocalOpenPointer(LocalOpenPointer &&src) noexcept
|
||||||
} \
|
: LocalPointerBase<Type>(src.ptr) {
|
||||||
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
|
src.ptr=nullptr;
|
||||||
LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \
|
|
||||||
adoptInstead(p.release()); \
|
|
||||||
return *this; \
|
|
||||||
} \
|
|
||||||
void swap(LocalPointerClassName &other) noexcept { \
|
|
||||||
Type *temp=LocalPointerBase<Type>::ptr; \
|
|
||||||
LocalPointerBase<Type>::ptr=other.ptr; \
|
|
||||||
other.ptr=temp; \
|
|
||||||
} \
|
|
||||||
friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) noexcept { \
|
|
||||||
p1.swap(p2); \
|
|
||||||
} \
|
|
||||||
void adoptInstead(Type *p) { \
|
|
||||||
if (ptr != nullptr) { closeFunction(ptr); } \
|
|
||||||
ptr=p; \
|
|
||||||
} \
|
|
||||||
operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
|
|
||||||
return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */
|
||||||
|
explicit LocalOpenPointer(std::unique_ptr<Type, decltype(closeFunction)> &&p)
|
||||||
|
: LocalPointerBase<Type>(p.release()) {}
|
||||||
|
~LocalOpenPointer() { if (ptr != nullptr) { closeFunction(ptr); } }
|
||||||
|
LocalOpenPointer &operator=(LocalOpenPointer &&src) noexcept {
|
||||||
|
if (ptr != nullptr) { closeFunction(ptr); }
|
||||||
|
LocalPointerBase<Type>::ptr=src.ptr;
|
||||||
|
src.ptr=nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */
|
||||||
|
LocalOpenPointer &operator=(std::unique_ptr<Type, decltype(closeFunction)> &&p) {
|
||||||
|
adoptInstead(p.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void swap(LocalOpenPointer &other) noexcept {
|
||||||
|
Type *temp=LocalPointerBase<Type>::ptr;
|
||||||
|
LocalPointerBase<Type>::ptr=other.ptr;
|
||||||
|
other.ptr=temp;
|
||||||
|
}
|
||||||
|
friend inline void swap(LocalOpenPointer &p1, LocalOpenPointer &p2) noexcept {
|
||||||
|
p1.swap(p2);
|
||||||
|
}
|
||||||
|
void adoptInstead(Type *p) {
|
||||||
|
if (ptr != nullptr) { closeFunction(ptr); }
|
||||||
|
ptr=p;
|
||||||
|
}
|
||||||
|
operator std::unique_ptr<Type, decltype(closeFunction)> () && {
|
||||||
|
return std::unique_ptr<Type, decltype(closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace internal
|
||||||
|
#endif
|
||||||
|
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
@ -195,51 +195,50 @@ class UnicodeString;
|
||||||
class U_COMMON_API Locale : public UObject {
|
class U_COMMON_API Locale : public UObject {
|
||||||
public:
|
public:
|
||||||
/** Useful constant for the Root locale. @stable ICU 4.4 */
|
/** Useful constant for the Root locale. @stable ICU 4.4 */
|
||||||
static const Locale &U_EXPORT2 getRoot(void);
|
static const Locale& U_EXPORT2 getRoot();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getEnglish(void);
|
static const Locale& U_EXPORT2 getEnglish();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getFrench(void);
|
static const Locale& U_EXPORT2 getFrench();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getGerman(void);
|
static const Locale& U_EXPORT2 getGerman();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getItalian(void);
|
static const Locale& U_EXPORT2 getItalian();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getJapanese(void);
|
static const Locale& U_EXPORT2 getJapanese();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getKorean(void);
|
static const Locale& U_EXPORT2 getKorean();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getChinese(void);
|
static const Locale& U_EXPORT2 getChinese();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getSimplifiedChinese(void);
|
static const Locale& U_EXPORT2 getSimplifiedChinese();
|
||||||
/** Useful constant for this language. @stable ICU 2.0 */
|
/** Useful constant for this language. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getTraditionalChinese(void);
|
static const Locale& U_EXPORT2 getTraditionalChinese();
|
||||||
|
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getFrance(void);
|
static const Locale& U_EXPORT2 getFrance();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getGermany(void);
|
static const Locale& U_EXPORT2 getGermany();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getItaly(void);
|
static const Locale& U_EXPORT2 getItaly();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getJapan(void);
|
static const Locale& U_EXPORT2 getJapan();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getKorea(void);
|
static const Locale& U_EXPORT2 getKorea();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getChina(void);
|
static const Locale& U_EXPORT2 getChina();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getPRC(void);
|
static const Locale& U_EXPORT2 getPRC();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getTaiwan(void);
|
static const Locale& U_EXPORT2 getTaiwan();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getUK(void);
|
static const Locale& U_EXPORT2 getUK();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getUS(void);
|
static const Locale& U_EXPORT2 getUS();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getCanada(void);
|
static const Locale& U_EXPORT2 getCanada();
|
||||||
/** Useful constant for this country/region. @stable ICU 2.0 */
|
/** Useful constant for this country/region. @stable ICU 2.0 */
|
||||||
static const Locale &U_EXPORT2 getCanadaFrench(void);
|
static const Locale& U_EXPORT2 getCanadaFrench();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a default locale object, a Locale for the default locale ID.
|
* Construct a default locale object, a Locale for the default locale ID.
|
||||||
|
@ -274,10 +273,10 @@ public:
|
||||||
* @see uloc_getDefault
|
* @see uloc_getDefault
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
Locale( const char * language,
|
Locale(const char* language,
|
||||||
const char * country = 0,
|
const char* country = nullptr,
|
||||||
const char * variant = 0,
|
const char* variant = nullptr,
|
||||||
const char * keywordsAndValues = 0);
|
const char* keywordsAndValues = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a Locale object from another Locale object.
|
* Initializes a Locale object from another Locale object.
|
||||||
|
@ -370,7 +369,7 @@ public:
|
||||||
* @system
|
* @system
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
static const Locale& U_EXPORT2 getDefault(void);
|
static const Locale& U_EXPORT2 getDefault();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default. Normally set once at the beginning of a process,
|
* Sets the default. Normally set once at the beginning of a process,
|
||||||
|
@ -518,20 +517,20 @@ public:
|
||||||
* If this Locale is already in the maximal form, or not valid, or there is
|
* If this Locale is already in the maximal form, or not valid, or there is
|
||||||
* no data available for maximization, the Locale will be unchanged.
|
* no data available for maximization, the Locale will be unchanged.
|
||||||
*
|
*
|
||||||
* For example, "und-Zzzz" cannot be maximized, since there is no
|
* For example, "sh" cannot be maximized, since there is no
|
||||||
* reasonable maximization.
|
* reasonable maximization.
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
*
|
*
|
||||||
|
* "und_Zzzz" maximizes to "en_Latn_US"
|
||||||
|
*
|
||||||
* "en" maximizes to "en_Latn_US"
|
* "en" maximizes to "en_Latn_US"
|
||||||
*
|
*
|
||||||
* "de" maximizes to "de_Latn_US"
|
* "de" maximizes to "de_Latn_DE"
|
||||||
*
|
*
|
||||||
* "sr" maximizes to "sr_Cyrl_RS"
|
* "sr" maximizes to "sr_Cyrl_RS"
|
||||||
*
|
*
|
||||||
* "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.)
|
* "zh_Hani" maximizes to "zh_Hani_CN"
|
||||||
*
|
|
||||||
* "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.)
|
|
||||||
*
|
*
|
||||||
* @param status error information if maximizing this Locale failed.
|
* @param status error information if maximizing this Locale failed.
|
||||||
* If this Locale is not well-formed, the error code is
|
* If this Locale is not well-formed, the error code is
|
||||||
|
@ -792,7 +791,7 @@ public:
|
||||||
* there is no Windows LCID value that corresponds to this locale, returns 0.
|
* there is no Windows LCID value that corresponds to this locale, returns 0.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
uint32_t getLCID(void) const;
|
uint32_t getLCID() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this locale's script is written right-to-left.
|
* Returns whether this locale's script is written right-to-left.
|
||||||
|
@ -944,7 +943,7 @@ public:
|
||||||
* Generates a hash code for the locale.
|
* Generates a hash code for the locale.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
int32_t hashCode(void) const;
|
int32_t hashCode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the locale to bogus
|
* Sets the locale to bogus
|
||||||
|
@ -961,7 +960,7 @@ public:
|
||||||
* @return false if it is a real locale, true if it is a bogus locale
|
* @return false if it is a real locale, true if it is a bogus locale
|
||||||
* @stable ICU 2.1
|
* @stable ICU 2.1
|
||||||
*/
|
*/
|
||||||
inline UBool isBogus(void) const;
|
inline UBool isBogus() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all installed locales.
|
* Returns a list of all installed locales.
|
||||||
|
@ -1147,7 +1146,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Initialize the locale cache for commonly used locales
|
* Initialize the locale cache for commonly used locales
|
||||||
*/
|
*/
|
||||||
static Locale *getLocaleCache(void);
|
static Locale* getLocaleCache();
|
||||||
|
|
||||||
char language[ULOC_LANG_CAPACITY];
|
char language[ULOC_LANG_CAPACITY];
|
||||||
char script[ULOC_SCRIPT_CAPACITY];
|
char script[ULOC_SCRIPT_CAPACITY];
|
||||||
|
@ -1184,6 +1183,7 @@ Locale::operator!=(const Locale& other) const
|
||||||
template<typename StringClass> inline StringClass
|
template<typename StringClass> inline StringClass
|
||||||
Locale::toLanguageTag(UErrorCode& status) const
|
Locale::toLanguageTag(UErrorCode& status) const
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return {}; }
|
||||||
StringClass result;
|
StringClass result;
|
||||||
StringByteSink<StringClass> sink(&result);
|
StringByteSink<StringClass> sink(&result);
|
||||||
toLanguageTag(sink, status);
|
toLanguageTag(sink, status);
|
||||||
|
@ -1211,7 +1211,7 @@ Locale::getScript() const
|
||||||
inline const char *
|
inline const char *
|
||||||
Locale::getVariant() const
|
Locale::getVariant() const
|
||||||
{
|
{
|
||||||
return &baseName[variantBegin];
|
return fIsBogus ? "" : &baseName[variantBegin];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *
|
inline const char *
|
||||||
|
@ -1223,6 +1223,7 @@ Locale::getName() const
|
||||||
template<typename StringClass, typename OutputIterator> inline void
|
template<typename StringClass, typename OutputIterator> inline void
|
||||||
Locale::getKeywords(OutputIterator iterator, UErrorCode& status) const
|
Locale::getKeywords(OutputIterator iterator, UErrorCode& status) const
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return; }
|
||||||
LocalPointer<StringEnumeration> keys(createKeywords(status));
|
LocalPointer<StringEnumeration> keys(createKeywords(status));
|
||||||
if (U_FAILURE(status) || keys.isNull()) {
|
if (U_FAILURE(status) || keys.isNull()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1240,6 +1241,7 @@ Locale::getKeywords(OutputIterator iterator, UErrorCode& status) const
|
||||||
template<typename StringClass, typename OutputIterator> inline void
|
template<typename StringClass, typename OutputIterator> inline void
|
||||||
Locale::getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const
|
Locale::getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return; }
|
||||||
LocalPointer<StringEnumeration> keys(createUnicodeKeywords(status));
|
LocalPointer<StringEnumeration> keys(createUnicodeKeywords(status));
|
||||||
if (U_FAILURE(status) || keys.isNull()) {
|
if (U_FAILURE(status) || keys.isNull()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1257,6 +1259,7 @@ Locale::getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const
|
||||||
template<typename StringClass> inline StringClass
|
template<typename StringClass> inline StringClass
|
||||||
Locale::getKeywordValue(StringPiece keywordName, UErrorCode& status) const
|
Locale::getKeywordValue(StringPiece keywordName, UErrorCode& status) const
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return {}; }
|
||||||
StringClass result;
|
StringClass result;
|
||||||
StringByteSink<StringClass> sink(&result);
|
StringByteSink<StringClass> sink(&result);
|
||||||
getKeywordValue(keywordName, sink, status);
|
getKeywordValue(keywordName, sink, status);
|
||||||
|
@ -1266,6 +1269,7 @@ Locale::getKeywordValue(StringPiece keywordName, UErrorCode& status) const
|
||||||
template<typename StringClass> inline StringClass
|
template<typename StringClass> inline StringClass
|
||||||
Locale::getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const
|
Locale::getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const
|
||||||
{
|
{
|
||||||
|
if (U_FAILURE(status)) { return {}; }
|
||||||
StringClass result;
|
StringClass result;
|
||||||
StringByteSink<StringClass> sink(&result);
|
StringByteSink<StringClass> sink(&result);
|
||||||
getUnicodeKeywordValue(keywordName, sink, status);
|
getUnicodeKeywordValue(keywordName, sink, status);
|
||||||
|
@ -1273,7 +1277,7 @@ Locale::getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
inline UBool
|
inline UBool
|
||||||
Locale::isBogus(void) const {
|
Locale::isBogus() const {
|
||||||
return fIsBogus;
|
return fIsBogus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -466,7 +466,7 @@ public:
|
||||||
* @return the current normalized code point
|
* @return the current normalized code point
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
UChar32 current(void);
|
UChar32 current();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first character in the normalized text.
|
* Return the first character in the normalized text.
|
||||||
|
@ -476,7 +476,7 @@ public:
|
||||||
* @return the first normalized code point
|
* @return the first normalized code point
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
UChar32 first(void);
|
UChar32 first();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last character in the normalized text.
|
* Return the last character in the normalized text.
|
||||||
|
@ -486,7 +486,7 @@ public:
|
||||||
* @return the last normalized code point
|
* @return the last normalized code point
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
UChar32 last(void);
|
UChar32 last();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the next character in the normalized text.
|
* Return the next character in the normalized text.
|
||||||
|
@ -502,7 +502,7 @@ public:
|
||||||
* @return the next normalized code point
|
* @return the next normalized code point
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
UChar32 next(void);
|
UChar32 next();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the previous character in the normalized text and decrement.
|
* Return the previous character in the normalized text and decrement.
|
||||||
|
@ -518,7 +518,7 @@ public:
|
||||||
* @return the previous normalized code point
|
* @return the previous normalized code point
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
UChar32 previous(void);
|
UChar32 previous();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the iteration position in the input text that is being normalized,
|
* Set the iteration position in the input text that is being normalized,
|
||||||
|
@ -536,7 +536,7 @@ public:
|
||||||
* This is equivalent to setIndexOnly(startIndex)).
|
* This is equivalent to setIndexOnly(startIndex)).
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
void reset(void);
|
void reset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the current iteration position in the input text that is
|
* Retrieve the current iteration position in the input text that is
|
||||||
|
@ -552,7 +552,7 @@ public:
|
||||||
* @return the current index in the input text
|
* @return the current index in the input text
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
int32_t getIndex(void) const;
|
int32_t getIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the index of the start of the input text. This is the begin index
|
* Retrieve the index of the start of the input text. This is the begin index
|
||||||
|
@ -562,7 +562,7 @@ public:
|
||||||
* @return the smallest index in the input text where the Normalizer operates
|
* @return the smallest index in the input text where the Normalizer operates
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
int32_t startIndex(void) const;
|
int32_t startIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the index of the end of the input text. This is the end index
|
* Retrieve the index of the end of the input text. This is the end index
|
||||||
|
@ -574,7 +574,7 @@ public:
|
||||||
* @return the first index in the input text where the Normalizer does not operate
|
* @return the first index in the input text where the Normalizer does not operate
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
int32_t endIndex(void) const;
|
int32_t endIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true when both iterators refer to the same character in the same
|
* Returns true when both iterators refer to the same character in the same
|
||||||
|
@ -610,7 +610,7 @@ public:
|
||||||
* @return the hash code
|
* @return the hash code
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
int32_t hashCode(void) const;
|
int32_t hashCode() const;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Property access methods
|
// Property access methods
|
||||||
|
@ -643,7 +643,7 @@ public:
|
||||||
* @see #setMode
|
* @see #setMode
|
||||||
* @deprecated ICU 56 Use Normalizer2 instead.
|
* @deprecated ICU 56 Use Normalizer2 instead.
|
||||||
*/
|
*/
|
||||||
UNormalizationMode getUMode(void) const;
|
UNormalizationMode getUMode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set options that affect this <code>Normalizer</code>'s operation.
|
* Set options that affect this <code>Normalizer</code>'s operation.
|
||||||
|
@ -749,7 +749,7 @@ private:
|
||||||
UBool previousNormalize();
|
UBool previousNormalize();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void clearBuffer(void);
|
void clearBuffer();
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Private data
|
// Private data
|
||||||
|
|
|
@ -129,7 +129,7 @@ public:
|
||||||
* @return the current index.
|
* @return the current index.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t getIndex(void) const;
|
inline int32_t getIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current parse position.
|
* Set the current parse position.
|
||||||
|
@ -152,7 +152,7 @@ public:
|
||||||
* error index has not been set.
|
* error index has not been set.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t getErrorIndex(void) const;
|
inline int32_t getErrorIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ICU "poor man's RTTI", returns a UClassID for this class.
|
* ICU "poor man's RTTI", returns a UClassID for this class.
|
||||||
|
|
|
@ -206,6 +206,17 @@
|
||||||
# define U_PLATFORM U_PF_UNKNOWN
|
# define U_PLATFORM U_PF_UNKNOWN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def U_REAL_MSVC
|
||||||
|
* Defined if the compiler is the real MSVC compiler (and not something like
|
||||||
|
* Clang setting _MSC_VER in order to compile Windows code that requires it).
|
||||||
|
* Otherwise undefined.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
#if (defined(_MSC_VER) && !(defined(__clang__) && __clang__)) || defined(U_IN_DOXYGEN)
|
||||||
|
# define U_REAL_MSVC
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \def CYGWINMSVC
|
* \def CYGWINMSVC
|
||||||
* Defined if this is Windows with Cygwin, but using MSVC rather than gcc.
|
* Defined if this is Windows with Cygwin, but using MSVC rather than gcc.
|
||||||
|
@ -302,51 +313,6 @@
|
||||||
# define U_PLATFORM_IS_DARWIN_BASED 0
|
# define U_PLATFORM_IS_DARWIN_BASED 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* \def U_HAVE_STDINT_H
|
|
||||||
* Defines whether stdint.h is available. It is a C99 standard header.
|
|
||||||
* We used to include inttypes.h which includes stdint.h but we usually do not need
|
|
||||||
* the additional definitions from inttypes.h.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
#ifdef U_HAVE_STDINT_H
|
|
||||||
/* Use the predefined value. */
|
|
||||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
|
||||||
# if defined(__BORLANDC__) || U_PLATFORM == U_PF_MINGW || (defined(_MSC_VER) && _MSC_VER>=1600)
|
|
||||||
/* Windows Visual Studio 9 and below do not have stdint.h & inttypes.h, but VS 2010 adds them. */
|
|
||||||
# define U_HAVE_STDINT_H 1
|
|
||||||
# else
|
|
||||||
# define U_HAVE_STDINT_H 0
|
|
||||||
# endif
|
|
||||||
#elif U_PLATFORM == U_PF_SOLARIS
|
|
||||||
/* Solaris has inttypes.h but not stdint.h. */
|
|
||||||
# define U_HAVE_STDINT_H 0
|
|
||||||
#elif U_PLATFORM == U_PF_AIX && !defined(_AIX51) && defined(_POWER)
|
|
||||||
/* PPC AIX <= 4.3 has inttypes.h but not stdint.h. */
|
|
||||||
# define U_HAVE_STDINT_H 0
|
|
||||||
#else
|
|
||||||
# define U_HAVE_STDINT_H 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \def U_HAVE_INTTYPES_H
|
|
||||||
* Defines whether inttypes.h is available. It is a C99 standard header.
|
|
||||||
* We include inttypes.h where it is available but stdint.h is not.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
#ifdef U_HAVE_INTTYPES_H
|
|
||||||
/* Use the predefined value. */
|
|
||||||
#elif U_PLATFORM == U_PF_SOLARIS
|
|
||||||
/* Solaris has inttypes.h but not stdint.h. */
|
|
||||||
# define U_HAVE_INTTYPES_H 1
|
|
||||||
#elif U_PLATFORM == U_PF_AIX && !defined(_AIX51) && defined(_POWER)
|
|
||||||
/* PPC AIX <= 4.3 has inttypes.h but not stdint.h. */
|
|
||||||
# define U_HAVE_INTTYPES_H 1
|
|
||||||
#else
|
|
||||||
/* Most platforms have both inttypes.h and stdint.h, or neither. */
|
|
||||||
# define U_HAVE_INTTYPES_H U_HAVE_STDINT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/** @{ Compiler and environment features */
|
/** @{ Compiler and environment features */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -507,6 +473,8 @@
|
||||||
/* Otherwise use the predefined value. */
|
/* Otherwise use the predefined value. */
|
||||||
#elif !defined(__cplusplus)
|
#elif !defined(__cplusplus)
|
||||||
# define U_CPLUSPLUS_VERSION 0
|
# define U_CPLUSPLUS_VERSION 0
|
||||||
|
#elif __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||||
|
# define U_CPLUSPLUS_VERSION 17
|
||||||
#elif __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
#elif __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||||
# define U_CPLUSPLUS_VERSION 14
|
# define U_CPLUSPLUS_VERSION 14
|
||||||
#elif __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
|
#elif __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
|
||||||
|
@ -754,9 +722,9 @@
|
||||||
/*
|
/*
|
||||||
* Notes:
|
* Notes:
|
||||||
* C++11 and C11 require support for UTF-16 literals
|
* C++11 and C11 require support for UTF-16 literals
|
||||||
* TODO: Fix for plain C. Doesn't work on Mac.
|
* Doesn't work on Mac C11 (see workaround in ptypes.h).
|
||||||
*/
|
*/
|
||||||
# if U_CPLUSPLUS_VERSION >= 11 || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
|
# if defined(__cplusplus) || !U_PLATFORM_IS_DARWIN_BASED
|
||||||
# define U_HAVE_CHAR16_T 1
|
# define U_HAVE_CHAR16_T 1
|
||||||
# else
|
# else
|
||||||
# define U_HAVE_CHAR16_T 0
|
# define U_HAVE_CHAR16_T 0
|
||||||
|
|
|
@ -42,89 +42,25 @@
|
||||||
/* NULL, size_t, wchar_t */
|
/* NULL, size_t, wchar_t */
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/*
|
/* More platform-specific definitions. */
|
||||||
* If all compilers provided all of the C99 headers and types,
|
|
||||||
* we would just unconditionally #include <stdint.h> here
|
|
||||||
* and not need any of the stuff after including platform.h.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Find out if we have stdint.h etc. */
|
|
||||||
#include "unicode/platform.h"
|
#include "unicode/platform.h"
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Generic data types */
|
/* Generic data types */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/* If your platform does not have the <stdint.h> header, you may
|
|
||||||
need to edit the typedefs in the #else section below.
|
|
||||||
Use #if...#else...#endif with predefined compiler macros if possible. */
|
|
||||||
#if U_HAVE_STDINT_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We mostly need <stdint.h> (which defines the standard integer types) but not <inttypes.h>.
|
|
||||||
* <inttypes.h> includes <stdint.h> and adds the printf/scanf helpers PRId32, SCNx16 etc.
|
|
||||||
* which we almost never use, plus stuff like imaxabs() which we never use.
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if U_PLATFORM == U_PF_OS390
|
// C++11 and C11 both specify that the data type char16_t should exist, C++11
|
||||||
/* The features header is needed to get (u)int64_t sometimes. */
|
// as a keyword and C11 as a typedef in the uchar.h header file, but not all
|
||||||
#include <features.h>
|
// implementations (looking at you, Apple, spring 2024) actually do this, so
|
||||||
/* z/OS has <stdint.h>, but some versions are missing uint8_t (APAR PK62248). */
|
// ICU4C must detect and deal with that.
|
||||||
#if !defined(__uint8_t)
|
#if !defined(__cplusplus) && !defined(U_IN_DOXYGEN)
|
||||||
#define __uint8_t 1
|
# if U_HAVE_CHAR16_T
|
||||||
typedef unsigned char uint8_t;
|
# include <uchar.h>
|
||||||
|
# else
|
||||||
|
typedef uint16_t char16_t;
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#endif /* U_PLATFORM == U_PF_OS390 */
|
|
||||||
|
|
||||||
#elif U_HAVE_INTTYPES_H
|
|
||||||
|
|
||||||
# include <inttypes.h>
|
|
||||||
|
|
||||||
#else /* neither U_HAVE_STDINT_H nor U_HAVE_INTTYPES_H */
|
|
||||||
|
|
||||||
/// \cond
|
|
||||||
#if ! U_HAVE_INT8_T
|
|
||||||
typedef signed char int8_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_UINT8_T
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_INT16_T
|
|
||||||
typedef signed short int16_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_UINT16_T
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_INT32_T
|
|
||||||
typedef signed int int32_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_UINT32_T
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_INT64_T
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef signed __int64 int64_t;
|
|
||||||
#else
|
|
||||||
typedef signed long long int64_t;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! U_HAVE_UINT64_T
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
#endif /* U_HAVE_STDINT_H / U_HAVE_INTTYPES_H */
|
|
||||||
|
|
||||||
#endif /* _PTYPES_H */
|
#endif /* _PTYPES_H */
|
||||||
|
|
|
@ -44,7 +44,7 @@ class UnhandledEngine;
|
||||||
class UStack;
|
class UStack;
|
||||||
|
|
||||||
|
|
||||||
#ifndef U_HIDE_DRAFT_API
|
#ifndef U_HIDE_INTERNAL_API
|
||||||
/**
|
/**
|
||||||
* The ExternalBreakEngine class define an abstract interface for the host environment
|
* The ExternalBreakEngine class define an abstract interface for the host environment
|
||||||
* to provide a low level facility to break text for unicode text in script that the text boundary
|
* to provide a low level facility to break text for unicode text in script that the text boundary
|
||||||
|
@ -103,7 +103,7 @@ class ExternalBreakEngine : public UObject {
|
||||||
int32_t* foundBreaks, int32_t foundBreaksCapacity,
|
int32_t* foundBreaks, int32_t foundBreaksCapacity,
|
||||||
UErrorCode& status) const = 0;
|
UErrorCode& status) const = 0;
|
||||||
};
|
};
|
||||||
#endif /* U_HIDE_DRAFT_API */
|
#endif /* U_HIDE_INTERNAL_API */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -388,14 +388,14 @@ public:
|
||||||
* @return A hash code
|
* @return A hash code
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t hashCode(void) const;
|
virtual int32_t hashCode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the description used to create this iterator
|
* Returns the description used to create this iterator
|
||||||
* @return the description used to create this iterator
|
* @return the description used to create this iterator
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual const UnicodeString& getRules(void) const;
|
virtual const UnicodeString& getRules() const;
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// BreakIterator overrides
|
// BreakIterator overrides
|
||||||
|
@ -425,8 +425,7 @@ public:
|
||||||
* @return An iterator over the text being analyzed.
|
* @return An iterator over the text being analyzed.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual CharacterIterator& getText(void) const override;
|
virtual CharacterIterator& getText() const override;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a UText for the text being analyzed.
|
* Get a UText for the text being analyzed.
|
||||||
|
@ -486,14 +485,14 @@ public:
|
||||||
* @return The offset of the beginning of the text, zero.
|
* @return The offset of the beginning of the text, zero.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t first(void) override;
|
virtual int32_t first() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current iteration position to the end of the text.
|
* Sets the current iteration position to the end of the text.
|
||||||
* @return The text's past-the-end offset.
|
* @return The text's past-the-end offset.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t last(void) override;
|
virtual int32_t last() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances the iterator either forward or backward the specified number of steps.
|
* Advances the iterator either forward or backward the specified number of steps.
|
||||||
|
@ -512,14 +511,14 @@ public:
|
||||||
* @return The position of the first boundary after this one.
|
* @return The position of the first boundary after this one.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t next(void) override;
|
virtual int32_t next() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the iterator backwards, to the last boundary preceding this one.
|
* Moves the iterator backwards, to the last boundary preceding this one.
|
||||||
* @return The position of the last boundary position preceding this one.
|
* @return The position of the last boundary position preceding this one.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t previous(void) override;
|
virtual int32_t previous() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first boundary position following
|
* Sets the iterator to refer to the first boundary position following
|
||||||
|
@ -557,8 +556,7 @@ public:
|
||||||
* @return The current iteration position.
|
* @return The current iteration position.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t current(void) const override;
|
virtual int32_t current() const override;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the status tag from the break rule that determined the boundary at
|
* Return the status tag from the break rule that determined the boundary at
|
||||||
|
@ -629,7 +627,7 @@ public:
|
||||||
* other classes have different class IDs.
|
* other classes have different class IDs.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override;
|
virtual UClassID getDynamicClassID() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the class ID for this class. This is useful only for
|
* Returns the class ID for this class. This is useful only for
|
||||||
|
@ -642,7 +640,7 @@ public:
|
||||||
* @return The class ID for all objects of this class.
|
* @return The class ID for all objects of this class.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
static UClassID U_EXPORT2 getStaticClassID();
|
||||||
|
|
||||||
#ifndef U_FORCE_HIDE_DEPRECATED_API
|
#ifndef U_FORCE_HIDE_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
|
@ -799,7 +797,7 @@ private:
|
||||||
void dumpTables();
|
void dumpTables();
|
||||||
#endif /* U_HIDE_INTERNAL_API */
|
#endif /* U_HIDE_INTERNAL_API */
|
||||||
|
|
||||||
#ifndef U_HIDE_DRAFT_API
|
#ifndef U_HIDE_INTERNAL_API
|
||||||
/**
|
/**
|
||||||
* Register a new external break engine. The external break engine will be adopted.
|
* Register a new external break engine. The external break engine will be adopted.
|
||||||
* Because ICU may choose to cache break engine internally, this must
|
* Because ICU may choose to cache break engine internally, this must
|
||||||
|
@ -811,7 +809,7 @@ private:
|
||||||
*/
|
*/
|
||||||
static void U_EXPORT2 registerExternalBreakEngine(
|
static void U_EXPORT2 registerExternalBreakEngine(
|
||||||
ExternalBreakEngine* toAdopt, UErrorCode& status);
|
ExternalBreakEngine* toAdopt, UErrorCode& status);
|
||||||
#endif /* U_HIDE_DRAFT_API */
|
#endif /* U_HIDE_INTERNAL_API */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -209,8 +209,7 @@ public:
|
||||||
* @return number of resources in a given resource.
|
* @return number of resources in a given resource.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
int32_t
|
int32_t getSize() const;
|
||||||
getSize(void) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a string from a string resource type
|
* returns a string from a string resource type
|
||||||
|
@ -289,16 +288,14 @@ public:
|
||||||
* @return true if there are more elements, false if there is no more elements
|
* @return true if there are more elements, false if there is no more elements
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
UBool
|
UBool hasNext() const;
|
||||||
hasNext(void) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the internal context of a resource so that iteration starts from the first element.
|
* Resets the internal context of a resource so that iteration starts from the first element.
|
||||||
*
|
*
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
void
|
void resetIterator();
|
||||||
resetIterator(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the key associated with this resource. Not all the resources have a key - only
|
* Returns the key associated with this resource. Not all the resources have a key - only
|
||||||
|
@ -307,8 +304,7 @@ public:
|
||||||
* @return a key associated to this resource, or nullptr if it doesn't have a key
|
* @return a key associated to this resource, or nullptr if it doesn't have a key
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
const char*
|
const char* getKey() const;
|
||||||
getKey(void) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the locale ID of the resource bundle as a string.
|
* Gets the locale ID of the resource bundle as a string.
|
||||||
|
@ -317,9 +313,7 @@ public:
|
||||||
* @return the locale ID of the resource bundle as a string
|
* @return the locale ID of the resource bundle as a string
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
const char*
|
const char* getName() const;
|
||||||
getName(void) const;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type of a resource. Available types are defined in enum UResType
|
* Returns the type of a resource. Available types are defined in enum UResType
|
||||||
|
@ -327,8 +321,7 @@ public:
|
||||||
* @return type of the given resource.
|
* @return type of the given resource.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
UResType
|
UResType getType() const;
|
||||||
getType(void) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next resource in a given resource or nullptr if there are no more resources
|
* Returns the next resource in a given resource or nullptr if there are no more resources
|
||||||
|
@ -424,8 +417,7 @@ public:
|
||||||
* @see getVersion
|
* @see getVersion
|
||||||
* @deprecated ICU 2.8 Use getVersion instead.
|
* @deprecated ICU 2.8 Use getVersion instead.
|
||||||
*/
|
*/
|
||||||
const char*
|
const char* getVersionNumber() const;
|
||||||
getVersionNumber(void) const;
|
|
||||||
#endif /* U_HIDE_DEPRECATED_API */
|
#endif /* U_HIDE_DEPRECATED_API */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -445,8 +437,7 @@ public:
|
||||||
* @return a Locale object
|
* @return a Locale object
|
||||||
* @deprecated ICU 2.8 Use getLocale(ULocDataLocaleType type, UErrorCode &status) overload instead.
|
* @deprecated ICU 2.8 Use getLocale(ULocDataLocaleType type, UErrorCode &status) overload instead.
|
||||||
*/
|
*/
|
||||||
const Locale&
|
const Locale& getLocale() const;
|
||||||
getLocale(void) const;
|
|
||||||
#endif /* U_HIDE_DEPRECATED_API */
|
#endif /* U_HIDE_DEPRECATED_API */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -156,14 +156,14 @@ public:
|
||||||
* @return a class ID for this object.
|
* @return a class ID for this object.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override;
|
virtual UClassID getDynamicClassID() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a class ID for this class (not really public)
|
* Return a class ID for this class (not really public)
|
||||||
* @return a class ID for this class
|
* @return a class ID for this class
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
static UClassID U_EXPORT2 getStaticClassID();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,11 +25,9 @@
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// Forward declaration:
|
// Forward declaration:
|
||||||
namespace number {
|
namespace number::impl {
|
||||||
namespace impl {
|
|
||||||
class SimpleModifier;
|
class SimpleModifier;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats simple patterns like "{1} was born in {0}".
|
* Formats simple patterns like "{1} was born in {0}".
|
||||||
|
|
|
@ -130,13 +130,13 @@ class U_COMMON_API StringPiece : public UMemory {
|
||||||
* @stable ICU 65
|
* @stable ICU 65
|
||||||
*/
|
*/
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if<
|
typename = std::enable_if_t<
|
||||||
(std::is_same<decltype(T().data()), const char*>::value
|
(std::is_same_v<decltype(T().data()), const char*>
|
||||||
#if defined(__cpp_char8_t)
|
#if defined(__cpp_char8_t)
|
||||||
|| std::is_same<decltype(T().data()), const char8_t*>::value
|
|| std::is_same_v<decltype(T().data()), const char8_t*>
|
||||||
#endif
|
#endif
|
||||||
) &&
|
) &&
|
||||||
std::is_same<decltype(T().size()), size_t>::value>::type>
|
std::is_same_v<decltype(T().size()), size_t>>>
|
||||||
StringPiece(T str)
|
StringPiece(T str)
|
||||||
: ptr_(reinterpret_cast<const char*>(str.data())),
|
: ptr_(reinterpret_cast<const char*>(str.data())),
|
||||||
length_(static_cast<int32_t>(str.size())) {}
|
length_(static_cast<int32_t>(str.size())) {}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#ifndef UCHAR_H
|
#ifndef UCHAR_H
|
||||||
#define UCHAR_H
|
#define UCHAR_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "unicode/utypes.h"
|
#include "unicode/utypes.h"
|
||||||
#include "unicode/stringoptions.h"
|
#include "unicode/stringoptions.h"
|
||||||
#include "unicode/ucpmap.h"
|
#include "unicode/ucpmap.h"
|
||||||
|
@ -668,12 +669,21 @@ typedef enum UProperty {
|
||||||
* @stable ICU 63
|
* @stable ICU 63
|
||||||
*/
|
*/
|
||||||
UCHAR_VERTICAL_ORIENTATION=0x1018,
|
UCHAR_VERTICAL_ORIENTATION=0x1018,
|
||||||
|
#ifndef U_HIDE_DRAFT_API
|
||||||
|
/**
|
||||||
|
* Enumerated property Identifier_Status.
|
||||||
|
* Used for UTS #39 General Security Profile for Identifiers
|
||||||
|
* (https://www.unicode.org/reports/tr39/#General_Security_Profile).
|
||||||
|
* @draft ICU 75
|
||||||
|
*/
|
||||||
|
UCHAR_IDENTIFIER_STATUS=0x1019,
|
||||||
|
#endif // U_HIDE_DRAFT_API
|
||||||
#ifndef U_HIDE_DEPRECATED_API
|
#ifndef U_HIDE_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
* One more than the last constant for enumerated/integer Unicode properties.
|
* One more than the last constant for enumerated/integer Unicode properties.
|
||||||
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
|
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
|
||||||
*/
|
*/
|
||||||
UCHAR_INT_LIMIT=0x1019,
|
UCHAR_INT_LIMIT=0x101A,
|
||||||
#endif // U_HIDE_DEPRECATED_API
|
#endif // U_HIDE_DEPRECATED_API
|
||||||
|
|
||||||
/** Bitmask property General_Category_Mask.
|
/** Bitmask property General_Category_Mask.
|
||||||
|
@ -774,12 +784,28 @@ typedef enum UProperty {
|
||||||
UCHAR_SCRIPT_EXTENSIONS=0x7000,
|
UCHAR_SCRIPT_EXTENSIONS=0x7000,
|
||||||
/** First constant for Unicode properties with unusual value types. @stable ICU 4.6 */
|
/** First constant for Unicode properties with unusual value types. @stable ICU 4.6 */
|
||||||
UCHAR_OTHER_PROPERTY_START=UCHAR_SCRIPT_EXTENSIONS,
|
UCHAR_OTHER_PROPERTY_START=UCHAR_SCRIPT_EXTENSIONS,
|
||||||
|
#ifndef U_HIDE_DRAFT_API
|
||||||
|
/**
|
||||||
|
* Miscellaneous property Identifier_Type.
|
||||||
|
* Used for UTS #39 General Security Profile for Identifiers
|
||||||
|
* (https://www.unicode.org/reports/tr39/#General_Security_Profile).
|
||||||
|
*
|
||||||
|
* Corresponds to u_hasIDType() and u_getIDTypes().
|
||||||
|
*
|
||||||
|
* Each code point maps to a <i>set</i> of UIdentifierType values.
|
||||||
|
*
|
||||||
|
* @see u_hasIDType
|
||||||
|
* @see u_getIDTypes
|
||||||
|
* @draft ICU 75
|
||||||
|
*/
|
||||||
|
UCHAR_IDENTIFIER_TYPE=0x7001,
|
||||||
|
#endif // U_HIDE_DRAFT_API
|
||||||
#ifndef U_HIDE_DEPRECATED_API
|
#ifndef U_HIDE_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
* One more than the last constant for Unicode properties with unusual value types.
|
* One more than the last constant for Unicode properties with unusual value types.
|
||||||
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
|
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
|
||||||
*/
|
*/
|
||||||
UCHAR_OTHER_PROPERTY_LIMIT=0x7001,
|
UCHAR_OTHER_PROPERTY_LIMIT=0x7002,
|
||||||
#endif // U_HIDE_DEPRECATED_API
|
#endif // U_HIDE_DEPRECATED_API
|
||||||
|
|
||||||
/** Represents a nonexistent or invalid property or property value. @stable ICU 2.4 */
|
/** Represents a nonexistent or invalid property or property value. @stable ICU 2.4 */
|
||||||
|
@ -2701,6 +2727,68 @@ typedef enum UVerticalOrientation {
|
||||||
U_VO_UPRIGHT,
|
U_VO_UPRIGHT,
|
||||||
} UVerticalOrientation;
|
} UVerticalOrientation;
|
||||||
|
|
||||||
|
#ifndef U_HIDE_DRAFT_API
|
||||||
|
/**
|
||||||
|
* Identifier Status constants.
|
||||||
|
* See https://www.unicode.org/reports/tr39/#Identifier_Status_and_Type.
|
||||||
|
*
|
||||||
|
* @see UCHAR_IDENTIFIER_STATUS
|
||||||
|
* @draft ICU 75
|
||||||
|
*/
|
||||||
|
typedef enum UIdentifierStatus {
|
||||||
|
/*
|
||||||
|
* Note: UIdentifierStatus constants are parsed by preparseucd.py.
|
||||||
|
* It matches lines like
|
||||||
|
* U_ID_STATUS_<Unicode Identifier_Status value name>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_STATUS_RESTRICTED,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_STATUS_ALLOWED,
|
||||||
|
} UIdentifierStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifier Type constants.
|
||||||
|
* See https://www.unicode.org/reports/tr39/#Identifier_Status_and_Type.
|
||||||
|
*
|
||||||
|
* @see UCHAR_IDENTIFIER_TYPE
|
||||||
|
* @draft ICU 75
|
||||||
|
*/
|
||||||
|
typedef enum UIdentifierType {
|
||||||
|
/*
|
||||||
|
* Note: UIdentifierType constants are parsed by preparseucd.py.
|
||||||
|
* It matches lines like
|
||||||
|
* U_ID_TYPE_<Unicode Identifier_Type value name>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_NOT_CHARACTER,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_DEPRECATED,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_DEFAULT_IGNORABLE,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_NOT_NFKC,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_NOT_XID,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_EXCLUSION,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_OBSOLETE,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_TECHNICAL,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_UNCOMMON_USE,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_LIMITED_USE,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_INCLUSION,
|
||||||
|
/** @draft ICU 75 */
|
||||||
|
U_ID_TYPE_RECOMMENDED,
|
||||||
|
} UIdentifierType;
|
||||||
|
#endif // U_HIDE_DRAFT_API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check a binary Unicode property for a code point.
|
* Check a binary Unicode property for a code point.
|
||||||
*
|
*
|
||||||
|
@ -3905,6 +3993,59 @@ u_isIDStart(UChar32 c);
|
||||||
U_CAPI UBool U_EXPORT2
|
U_CAPI UBool U_EXPORT2
|
||||||
u_isIDPart(UChar32 c);
|
u_isIDPart(UChar32 c);
|
||||||
|
|
||||||
|
#ifndef U_HIDE_DRAFT_API
|
||||||
|
/**
|
||||||
|
* Does the set of Identifier_Type values code point c contain the given type?
|
||||||
|
*
|
||||||
|
* Used for UTS #39 General Security Profile for Identifiers
|
||||||
|
* (https://www.unicode.org/reports/tr39/#General_Security_Profile).
|
||||||
|
*
|
||||||
|
* Each code point maps to a <i>set</i> of UIdentifierType values.
|
||||||
|
*
|
||||||
|
* @param c code point
|
||||||
|
* @param type Identifier_Type to check
|
||||||
|
* @return true if type is in Identifier_Type(c)
|
||||||
|
* @draft ICU 75
|
||||||
|
*/
|
||||||
|
U_CAPI bool U_EXPORT2
|
||||||
|
u_hasIDType(UChar32 c, UIdentifierType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes code point c's Identifier_Type as a list of UIdentifierType values
|
||||||
|
* to the output types array and returns the number of types.
|
||||||
|
*
|
||||||
|
* Used for UTS #39 General Security Profile for Identifiers
|
||||||
|
* (https://www.unicode.org/reports/tr39/#General_Security_Profile).
|
||||||
|
*
|
||||||
|
* Each code point maps to a <i>set</i> of UIdentifierType values.
|
||||||
|
* There is always at least one type.
|
||||||
|
* The order of output values is undefined.
|
||||||
|
* Each type is output at most once;
|
||||||
|
* there cannot be more output values than UIdentifierType constants.
|
||||||
|
* In addition, only some of the types can be combined with others,
|
||||||
|
* and usually only a small number of types occur together.
|
||||||
|
* Future versions might add additional types.
|
||||||
|
* See UTS #39 and its data files for details.
|
||||||
|
*
|
||||||
|
* If there are more than capacity types to be written, then
|
||||||
|
* U_BUFFER_OVERFLOW_ERROR is set and the number of types is returned.
|
||||||
|
* (Usual ICU buffer handling behavior.)
|
||||||
|
*
|
||||||
|
* @param c code point
|
||||||
|
* @param types output array
|
||||||
|
* @param capacity capacity of the array
|
||||||
|
* @param pErrorCode Standard ICU error code. Its input value must
|
||||||
|
* pass the U_SUCCESS() test, or else the function returns
|
||||||
|
* immediately. Check for U_FAILURE() on output or use with
|
||||||
|
* function chaining. (See User Guide for details.)
|
||||||
|
* @return number of values in c's Identifier_Type,
|
||||||
|
* written to types unless U_BUFFER_OVERFLOW_ERROR indicates insufficient capacity
|
||||||
|
* @draft ICU 75
|
||||||
|
*/
|
||||||
|
U_CAPI int32_t U_EXPORT2
|
||||||
|
u_getIDTypes(UChar32 c, UIdentifierType *types, int32_t capacity, UErrorCode *pErrorCode);
|
||||||
|
#endif // U_HIDE_DRAFT_API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the specified character should be regarded
|
* Determines if the specified character should be regarded
|
||||||
* as an ignorable character in an identifier,
|
* as an ignorable character in an identifier,
|
||||||
|
|
|
@ -126,7 +126,7 @@ public:
|
||||||
* @return the hash code.
|
* @return the hash code.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t hashCode(void) const override;
|
virtual int32_t hashCode() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new UCharCharacterIterator referring to the same
|
* Returns a new UCharCharacterIterator referring to the same
|
||||||
|
@ -144,7 +144,7 @@ public:
|
||||||
* @return the first code unit in its iteration range.
|
* @return the first code unit in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t first(void) override;
|
virtual char16_t first() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code unit in its
|
* Sets the iterator to refer to the first code unit in its
|
||||||
|
@ -154,7 +154,7 @@ public:
|
||||||
* @return the first code unit in its iteration range
|
* @return the first code unit in its iteration range
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t firstPostInc(void) override;
|
virtual char16_t firstPostInc() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code point in its
|
* Sets the iterator to refer to the first code point in its
|
||||||
|
@ -165,7 +165,7 @@ public:
|
||||||
* @return the first code point in its iteration range
|
* @return the first code point in its iteration range
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 first32(void) override;
|
virtual UChar32 first32() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the first code point in its
|
* Sets the iterator to refer to the first code point in its
|
||||||
|
@ -175,7 +175,7 @@ public:
|
||||||
* @return the first code point in its iteration range.
|
* @return the first code point in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 first32PostInc(void) override;
|
virtual UChar32 first32PostInc() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the last code unit in its
|
* Sets the iterator to refer to the last code unit in its
|
||||||
|
@ -184,7 +184,7 @@ public:
|
||||||
* @return the last code unit in its iteration range.
|
* @return the last code unit in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t last(void) override;
|
virtual char16_t last() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the last code point in its
|
* Sets the iterator to refer to the last code point in its
|
||||||
|
@ -193,7 +193,7 @@ public:
|
||||||
* @return the last code point in its iteration range.
|
* @return the last code point in its iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 last32(void) override;
|
virtual UChar32 last32() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the iterator to refer to the "position"-th code unit
|
* Sets the iterator to refer to the "position"-th code unit
|
||||||
|
@ -223,14 +223,14 @@ public:
|
||||||
* @return the code unit the iterator currently refers to.
|
* @return the code unit the iterator currently refers to.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t current(void) const override;
|
virtual char16_t current() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the code point the iterator currently refers to.
|
* Returns the code point the iterator currently refers to.
|
||||||
* @return the code point the iterator currently refers to.
|
* @return the code point the iterator currently refers to.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 current32(void) const override;
|
virtual UChar32 current32() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the next code unit in the iteration range (toward
|
* Advances to the next code unit in the iteration range (toward
|
||||||
|
@ -239,7 +239,7 @@ public:
|
||||||
* @return the next code unit in the iteration range.
|
* @return the next code unit in the iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t next(void) override;
|
virtual char16_t next() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current code unit for returning and advances to the next code unit
|
* Gets the current code unit for returning and advances to the next code unit
|
||||||
|
@ -249,7 +249,7 @@ public:
|
||||||
* @return the current code unit.
|
* @return the current code unit.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t nextPostInc(void) override;
|
virtual char16_t nextPostInc() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the next code point in the iteration range (toward
|
* Advances to the next code point in the iteration range (toward
|
||||||
|
@ -261,7 +261,7 @@ public:
|
||||||
* @return the next code point in the iteration range.
|
* @return the next code point in the iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 next32(void) override;
|
virtual UChar32 next32() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current code point for returning and advances to the next code point
|
* Gets the current code point for returning and advances to the next code point
|
||||||
|
@ -271,7 +271,7 @@ public:
|
||||||
* @return the current point.
|
* @return the current point.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 next32PostInc(void) override;
|
virtual UChar32 next32PostInc() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns false if there are no more code units or code points
|
* Returns false if there are no more code units or code points
|
||||||
|
@ -291,7 +291,7 @@ public:
|
||||||
* @return the previous code unit in the iteration range.
|
* @return the previous code unit in the iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual char16_t previous(void) override;
|
virtual char16_t previous() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advances to the previous code point in the iteration range (toward
|
* Advances to the previous code point in the iteration range (toward
|
||||||
|
@ -300,7 +300,7 @@ public:
|
||||||
* @return the previous code point in the iteration range.
|
* @return the previous code point in the iteration range.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UChar32 previous32(void) override;
|
virtual UChar32 previous32() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns false if there are no more code units or code points
|
* Returns false if there are no more code units or code points
|
||||||
|
@ -363,14 +363,14 @@ public:
|
||||||
* @return a class ID for this class
|
* @return a class ID for this class
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
static UClassID U_EXPORT2 getStaticClassID();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a class ID for this object (not really public)
|
* Return a class ID for this object (not really public)
|
||||||
* @return a class ID for this object.
|
* @return a class ID for this object.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override;
|
virtual UClassID getDynamicClassID() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -344,8 +344,6 @@ ucnv_compareNames(const char *name1, const char *name2);
|
||||||
* other than its an alias starting with the letters "cp". Please do not
|
* other than its an alias starting with the letters "cp". Please do not
|
||||||
* associate any meaning to these aliases.</p>
|
* associate any meaning to these aliases.</p>
|
||||||
*
|
*
|
||||||
* \snippet samples/ucnv/convsamp.cpp ucnv_open
|
|
||||||
*
|
|
||||||
* @param converterName Name of the coded character set table.
|
* @param converterName Name of the coded character set table.
|
||||||
* This may have options appended to the string.
|
* This may have options appended to the string.
|
||||||
* IANA alias character set names, IBM CCSIDs starting with "ibm-",
|
* IANA alias character set names, IBM CCSIDs starting with "ibm-",
|
||||||
|
@ -1986,7 +1984,6 @@ ucnv_usesFallback(const UConverter *cnv);
|
||||||
* instead of the input signature bytes.
|
* instead of the input signature bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* Usage:
|
* Usage:
|
||||||
* \snippet samples/ucnv/convsamp.cpp ucnv_detectUnicodeSignature
|
|
||||||
*
|
*
|
||||||
* @param source The source string in which the signature should be detected.
|
* @param source The source string in which the signature should be detected.
|
||||||
* @param sourceLength Length of the input string, or -1 if terminated with a NUL byte.
|
* @param sourceLength Length of the input string, or -1 if terminated with a NUL byte.
|
||||||
|
|
|
@ -413,6 +413,17 @@
|
||||||
# define UCONFIG_NO_FORMATTING 0
|
# define UCONFIG_NO_FORMATTING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def UCONFIG_NO_MF2
|
||||||
|
* This switch turns off the experimental MessageFormat 2.0 API.
|
||||||
|
*
|
||||||
|
* @internal ICU 75 technology preview
|
||||||
|
* @deprecated This API is for technology preview only.
|
||||||
|
*/
|
||||||
|
#ifndef UCONFIG_NO_MF2
|
||||||
|
# define UCONFIG_NO_MF2 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \def UCONFIG_NO_TRANSLITERATION
|
* \def UCONFIG_NO_TRANSLITERATION
|
||||||
* This switch turns off transliteration.
|
* This switch turns off transliteration.
|
||||||
|
|
|
@ -399,6 +399,9 @@ uloc_setDefault(const char* localeID,
|
||||||
/**
|
/**
|
||||||
* Gets the language code for the specified locale.
|
* Gets the language code for the specified locale.
|
||||||
*
|
*
|
||||||
|
* This function may return with a failure error code for certain kinds of inputs
|
||||||
|
* but does not fully check for well-formed locale IDs / language tags.
|
||||||
|
*
|
||||||
* @param localeID the locale to get the ISO language code with
|
* @param localeID the locale to get the ISO language code with
|
||||||
* @param language the language code for localeID
|
* @param language the language code for localeID
|
||||||
* @param languageCapacity the size of the language buffer to store the
|
* @param languageCapacity the size of the language buffer to store the
|
||||||
|
@ -417,6 +420,9 @@ uloc_getLanguage(const char* localeID,
|
||||||
/**
|
/**
|
||||||
* Gets the script code for the specified locale.
|
* Gets the script code for the specified locale.
|
||||||
*
|
*
|
||||||
|
* This function may return with a failure error code for certain kinds of inputs
|
||||||
|
* but does not fully check for well-formed locale IDs / language tags.
|
||||||
|
*
|
||||||
* @param localeID the locale to get the ISO language code with
|
* @param localeID the locale to get the ISO language code with
|
||||||
* @param script the language code for localeID
|
* @param script the language code for localeID
|
||||||
* @param scriptCapacity the size of the language buffer to store the
|
* @param scriptCapacity the size of the language buffer to store the
|
||||||
|
@ -435,6 +441,9 @@ uloc_getScript(const char* localeID,
|
||||||
/**
|
/**
|
||||||
* Gets the country code for the specified locale.
|
* Gets the country code for the specified locale.
|
||||||
*
|
*
|
||||||
|
* This function may return with a failure error code for certain kinds of inputs
|
||||||
|
* but does not fully check for well-formed locale IDs / language tags.
|
||||||
|
*
|
||||||
* @param localeID the locale to get the country code with
|
* @param localeID the locale to get the country code with
|
||||||
* @param country the country code for localeID
|
* @param country the country code for localeID
|
||||||
* @param countryCapacity the size of the country buffer to store the
|
* @param countryCapacity the size of the country buffer to store the
|
||||||
|
@ -453,6 +462,9 @@ uloc_getCountry(const char* localeID,
|
||||||
/**
|
/**
|
||||||
* Gets the variant code for the specified locale.
|
* Gets the variant code for the specified locale.
|
||||||
*
|
*
|
||||||
|
* This function may return with a failure error code for certain kinds of inputs
|
||||||
|
* but does not fully check for well-formed locale IDs / language tags.
|
||||||
|
*
|
||||||
* @param localeID the locale to get the variant code with
|
* @param localeID the locale to get the variant code with
|
||||||
* @param variant the variant code for localeID
|
* @param variant the variant code for localeID
|
||||||
* @param variantCapacity the size of the variant buffer to store the
|
* @param variantCapacity the size of the variant buffer to store the
|
||||||
|
@ -471,6 +483,10 @@ uloc_getVariant(const char* localeID,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the full name for the specified locale.
|
* Gets the full name for the specified locale.
|
||||||
|
*
|
||||||
|
* This function may return with a failure error code for certain kinds of inputs
|
||||||
|
* but does not fully check for well-formed locale IDs / language tags.
|
||||||
|
*
|
||||||
* Note: This has the effect of 'canonicalizing' the ICU locale ID to
|
* Note: This has the effect of 'canonicalizing' the ICU locale ID to
|
||||||
* a certain extent. Upper and lower case are set as needed.
|
* a certain extent. Upper and lower case are set as needed.
|
||||||
* It does NOT map aliased names in any way.
|
* It does NOT map aliased names in any way.
|
||||||
|
@ -1158,19 +1174,20 @@ uloc_getLocaleForLCID(uint32_t hostID, char *locale, int32_t localeCapacity,
|
||||||
*
|
*
|
||||||
* If localeID is already in the maximal form, or there is no data available
|
* If localeID is already in the maximal form, or there is no data available
|
||||||
* for maximization, it will be copied to the output buffer. For example,
|
* for maximization, it will be copied to the output buffer. For example,
|
||||||
* "und-Zzzz" cannot be maximized, since there is no reasonable maximization.
|
* "sh" cannot be maximized, since there is no reasonable maximization.
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
*
|
*
|
||||||
|
* "und_Zzzz" maximizes to "en_Latn_US"
|
||||||
|
*
|
||||||
* "en" maximizes to "en_Latn_US"
|
* "en" maximizes to "en_Latn_US"
|
||||||
*
|
*
|
||||||
* "de" maximizes to "de_Latn_US"
|
* "de" maximizes to "de_Latn_DE"
|
||||||
*
|
*
|
||||||
* "sr" maximizes to "sr_Cyrl_RS"
|
* "sr" maximizes to "sr_Cyrl_RS"
|
||||||
*
|
*
|
||||||
* "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.)
|
* "zh_Hani" maximizes to "zh_Hani_CN"
|
||||||
*
|
*
|
||||||
* "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.)
|
|
||||||
*
|
*
|
||||||
* @param localeID The locale to maximize
|
* @param localeID The locale to maximize
|
||||||
* @param maximizedLocaleID The maximized locale
|
* @param maximizedLocaleID The maximized locale
|
||||||
|
|
|
@ -74,7 +74,7 @@ typedef struct ULocaleBuilder ULocaleBuilder;
|
||||||
* @draft ICU 74
|
* @draft ICU 74
|
||||||
*/
|
*/
|
||||||
U_CAPI ULocaleBuilder* U_EXPORT2
|
U_CAPI ULocaleBuilder* U_EXPORT2
|
||||||
ulocbld_open();
|
ulocbld_open(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the builder and destroy it's internal states.
|
* Close the builder and destroy it's internal states.
|
||||||
|
|
|
@ -370,22 +370,14 @@ typedef int8_t UBool;
|
||||||
#if 1
|
#if 1
|
||||||
// #if 1 is normal. UChar defaults to char16_t in C++.
|
// #if 1 is normal. UChar defaults to char16_t in C++.
|
||||||
// For configuration testing of UChar=uint16_t temporarily change this to #if 0.
|
// For configuration testing of UChar=uint16_t temporarily change this to #if 0.
|
||||||
// The intltest Makefile #defines UCHAR_TYPE=char16_t,
|
#else
|
||||||
// so we only #define it to uint16_t if it is undefined so far.
|
|
||||||
#elif !defined(UCHAR_TYPE)
|
|
||||||
# define UCHAR_TYPE uint16_t
|
# define UCHAR_TYPE uint16_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \
|
#if defined(U_ALL_IMPLEMENTATION) || !defined(UCHAR_TYPE)
|
||||||
defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION)
|
|
||||||
// Inside the ICU library code, never configurable.
|
|
||||||
typedef char16_t UChar;
|
typedef char16_t UChar;
|
||||||
#elif defined(UCHAR_TYPE)
|
|
||||||
typedef UCHAR_TYPE UChar;
|
|
||||||
#elif U_CPLUSPLUS_VERSION != 0
|
|
||||||
typedef char16_t UChar; // C++
|
|
||||||
#else
|
#else
|
||||||
typedef uint16_t UChar; // C
|
typedef UCHAR_TYPE UChar;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -83,7 +83,7 @@ public:
|
||||||
* @return The class ID for all objects of this class.
|
* @return The class ID for all objects of this class.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
static UClassID U_EXPORT2 getStaticClassID();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a unique class ID <b>polymorphically</b>. This method
|
* Returns a unique class ID <b>polymorphically</b>. This method
|
||||||
|
@ -100,7 +100,7 @@ public:
|
||||||
* different class IDs.
|
* different class IDs.
|
||||||
* @stable ICU 2.4
|
* @stable ICU 2.4
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override = 0;
|
virtual UClassID getDynamicClassID() const override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the data object associated with this functor. The data
|
* Set the data object associated with this functor. The data
|
||||||
|
|
|
@ -333,7 +333,7 @@ public:
|
||||||
* @see setToBogus()
|
* @see setToBogus()
|
||||||
* @stable ICU 4.0
|
* @stable ICU 4.0
|
||||||
*/
|
*/
|
||||||
inline UBool isBogus(void) const;
|
inline UBool isBogus() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make this UnicodeSet object invalid.
|
* Make this UnicodeSet object invalid.
|
||||||
|
@ -522,7 +522,7 @@ public:
|
||||||
* @see Object#hashCode()
|
* @see Object#hashCode()
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual int32_t hashCode(void) const;
|
virtual int32_t hashCode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a UnicodeSet pointer from a USet
|
* Get a UnicodeSet pointer from a USet
|
||||||
|
@ -792,7 +792,7 @@ public:
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
* @see getRangeCount
|
* @see getRangeCount
|
||||||
*/
|
*/
|
||||||
virtual int32_t size(void) const;
|
virtual int32_t size() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <tt>true</tt> if this set contains no elements.
|
* Returns <tt>true</tt> if this set contains no elements.
|
||||||
|
@ -800,7 +800,7 @@ public:
|
||||||
* @return <tt>true</tt> if this set contains no elements.
|
* @return <tt>true</tt> if this set contains no elements.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UBool isEmpty(void) const;
|
virtual UBool isEmpty() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this set contains multi-character strings or the empty string.
|
* @return true if this set contains multi-character strings or the empty string.
|
||||||
|
@ -1394,7 +1394,7 @@ public:
|
||||||
* A frozen set will not be modified.
|
* A frozen set will not be modified.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
virtual UnicodeSet& clear(void);
|
virtual UnicodeSet& clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close this set over the given attribute. For the attribute
|
* Close this set over the given attribute. For the attribute
|
||||||
|
@ -1440,7 +1440,7 @@ public:
|
||||||
* @see #getRangeEnd
|
* @see #getRangeEnd
|
||||||
* @stable ICU 2.4
|
* @stable ICU 2.4
|
||||||
*/
|
*/
|
||||||
virtual int32_t getRangeCount(void) const;
|
virtual int32_t getRangeCount() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iteration method that returns the first character in the
|
* Iteration method that returns the first character in the
|
||||||
|
@ -1529,7 +1529,7 @@ public:
|
||||||
* @return The class ID for all objects of this class.
|
* @return The class ID for all objects of this class.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
static UClassID U_EXPORT2 getStaticClassID();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement UnicodeFunctor API.
|
* Implement UnicodeFunctor API.
|
||||||
|
@ -1539,9 +1539,9 @@ public:
|
||||||
* different class IDs.
|
* different class IDs.
|
||||||
* @stable ICU 2.4
|
* @stable ICU 2.4
|
||||||
*/
|
*/
|
||||||
virtual UClassID getDynamicClassID(void) const override;
|
virtual UClassID getDynamicClassID() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Private API for the USet API
|
// Private API for the USet API
|
||||||
|
|
||||||
|
@ -1602,7 +1602,7 @@ private:
|
||||||
|
|
||||||
bool ensureBufferCapacity(int32_t newLen);
|
bool ensureBufferCapacity(int32_t newLen);
|
||||||
|
|
||||||
void swapBuffers(void);
|
void swapBuffers();
|
||||||
|
|
||||||
UBool allocateStrings(UErrorCode &status);
|
UBool allocateStrings(UErrorCode &status);
|
||||||
int32_t stringsSize() const;
|
int32_t stringsSize() const;
|
||||||
|
|
|
@ -1612,8 +1612,8 @@ public:
|
||||||
*/
|
*/
|
||||||
inline int32_t extract(int32_t start,
|
inline int32_t extract(int32_t start,
|
||||||
int32_t startLength,
|
int32_t startLength,
|
||||||
char *target,
|
char* target,
|
||||||
const char *codepage = 0) const;
|
const char* codepage = nullptr) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the characters in the range
|
* Copy the characters in the range
|
||||||
|
@ -1759,7 +1759,7 @@ public:
|
||||||
* @see countChar32
|
* @see countChar32
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t length(void) const;
|
inline int32_t length() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count Unicode code points in the length char16_t code units of the string.
|
* Count Unicode code points in the length char16_t code units of the string.
|
||||||
|
@ -1808,7 +1808,7 @@ public:
|
||||||
* @return true if this string contains 0 characters, false otherwise.
|
* @return true if this string contains 0 characters, false otherwise.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline UBool isEmpty(void) const;
|
inline UBool isEmpty() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the capacity of the internal buffer of the UnicodeString object.
|
* Return the capacity of the internal buffer of the UnicodeString object.
|
||||||
|
@ -1819,7 +1819,7 @@ public:
|
||||||
* @see getBuffer
|
* @see getBuffer
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t getCapacity(void) const;
|
inline int32_t getCapacity() const;
|
||||||
|
|
||||||
/* Other operations */
|
/* Other operations */
|
||||||
|
|
||||||
|
@ -1828,7 +1828,7 @@ public:
|
||||||
* @return The hash code of this UnicodeString.
|
* @return The hash code of this UnicodeString.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline int32_t hashCode(void) const;
|
inline int32_t hashCode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this object contains a valid string.
|
* Determine if this object contains a valid string.
|
||||||
|
@ -1842,8 +1842,7 @@ public:
|
||||||
* @see setToBogus()
|
* @see setToBogus()
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline UBool isBogus(void) const;
|
inline UBool isBogus() const;
|
||||||
|
|
||||||
|
|
||||||
//========================================
|
//========================================
|
||||||
// Write operations
|
// Write operations
|
||||||
|
@ -2624,8 +2623,7 @@ public:
|
||||||
* @return a reference to this
|
* @return a reference to this
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
UnicodeString& trim(void);
|
UnicodeString& trim();
|
||||||
|
|
||||||
|
|
||||||
/* Miscellaneous operations */
|
/* Miscellaneous operations */
|
||||||
|
|
||||||
|
@ -2634,7 +2632,7 @@ public:
|
||||||
* @return a reference to this
|
* @return a reference to this
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
inline UnicodeString& reverse(void);
|
inline UnicodeString& reverse();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse the range [`start`, `start + length`) in
|
* Reverse the range [`start`, `start + length`) in
|
||||||
|
@ -2653,7 +2651,7 @@ public:
|
||||||
* @return A reference to this.
|
* @return A reference to this.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
UnicodeString& toUpper(void);
|
UnicodeString& toUpper();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the characters in this to UPPER CASE following the conventions of
|
* Convert the characters in this to UPPER CASE following the conventions of
|
||||||
|
@ -2670,7 +2668,7 @@ public:
|
||||||
* @return A reference to this.
|
* @return A reference to this.
|
||||||
* @stable ICU 2.0
|
* @stable ICU 2.0
|
||||||
*/
|
*/
|
||||||
UnicodeString& toLower(void);
|
UnicodeString& toLower();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the characters in this to lower case following the conventions of
|
* Convert the characters in this to lower case following the conventions of
|
||||||
|
@ -3590,12 +3588,12 @@ private:
|
||||||
int32_t length);
|
int32_t length);
|
||||||
|
|
||||||
// calculate hash code
|
// calculate hash code
|
||||||
int32_t doHashCode(void) const;
|
int32_t doHashCode() const;
|
||||||
|
|
||||||
// get pointer to start of array
|
// get pointer to start of array
|
||||||
// these do not check for kOpenGetBuffer, unlike the public getBuffer() function
|
// these do not check for kOpenGetBuffer, unlike the public getBuffer() function
|
||||||
inline char16_t* getArrayStart(void);
|
inline char16_t* getArrayStart();
|
||||||
inline const char16_t* getArrayStart(void) const;
|
inline const char16_t* getArrayStart() const;
|
||||||
|
|
||||||
inline UBool hasShortLength() const;
|
inline UBool hasShortLength() const;
|
||||||
inline int32_t getShortLength() const;
|
inline int32_t getShortLength() const;
|
||||||
|
@ -3622,7 +3620,7 @@ private:
|
||||||
UBool allocate(int32_t capacity);
|
UBool allocate(int32_t capacity);
|
||||||
|
|
||||||
// release the array if owned
|
// release the array if owned
|
||||||
void releaseArray(void);
|
void releaseArray();
|
||||||
|
|
||||||
// turn a bogus string into an empty one
|
// turn a bogus string into an empty one
|
||||||
void unBogus();
|
void unBogus();
|
||||||
|
@ -3686,7 +3684,7 @@ private:
|
||||||
UBool cloneArrayIfNeeded(int32_t newCapacity = -1,
|
UBool cloneArrayIfNeeded(int32_t newCapacity = -1,
|
||||||
int32_t growCapacity = -1,
|
int32_t growCapacity = -1,
|
||||||
UBool doCopyArray = true,
|
UBool doCopyArray = true,
|
||||||
int32_t **pBufferToDelete = 0,
|
int32_t** pBufferToDelete = nullptr,
|
||||||
UBool forceClone = false);
|
UBool forceClone = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3702,9 +3700,9 @@ private:
|
||||||
UStringCaseMapper *stringCaseMapper);
|
UStringCaseMapper *stringCaseMapper);
|
||||||
|
|
||||||
// ref counting
|
// ref counting
|
||||||
void addRef(void);
|
void addRef();
|
||||||
int32_t removeRef(void);
|
int32_t removeRef();
|
||||||
int32_t refCount(void) const;
|
int32_t refCount() const;
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
enum {
|
enum {
|
||||||
|
@ -4510,7 +4508,7 @@ UnicodeString::extract(int32_t start,
|
||||||
|
|
||||||
{
|
{
|
||||||
// This dstSize value will be checked explicitly
|
// This dstSize value will be checked explicitly
|
||||||
return extract(start, _length, dst, dst!=0 ? 0xffffffff : 0, codepage);
|
return extract(start, _length, dst, dst != nullptr ? 0xffffffff : 0, codepage);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -272,6 +272,7 @@
|
||||||
#define u_getDataVersion U_ICU_ENTRY_POINT_RENAME(u_getDataVersion)
|
#define u_getDataVersion U_ICU_ENTRY_POINT_RENAME(u_getDataVersion)
|
||||||
#define u_getDefaultConverter U_ICU_ENTRY_POINT_RENAME(u_getDefaultConverter)
|
#define u_getDefaultConverter U_ICU_ENTRY_POINT_RENAME(u_getDefaultConverter)
|
||||||
#define u_getFC_NFKC_Closure U_ICU_ENTRY_POINT_RENAME(u_getFC_NFKC_Closure)
|
#define u_getFC_NFKC_Closure U_ICU_ENTRY_POINT_RENAME(u_getFC_NFKC_Closure)
|
||||||
|
#define u_getIDTypes U_ICU_ENTRY_POINT_RENAME(u_getIDTypes)
|
||||||
#define u_getISOComment U_ICU_ENTRY_POINT_RENAME(u_getISOComment)
|
#define u_getISOComment U_ICU_ENTRY_POINT_RENAME(u_getISOComment)
|
||||||
#define u_getIntPropertyMap U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMap)
|
#define u_getIntPropertyMap U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMap)
|
||||||
#define u_getIntPropertyMaxValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMaxValue)
|
#define u_getIntPropertyMaxValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMaxValue)
|
||||||
|
@ -289,6 +290,7 @@
|
||||||
#define u_getVersion U_ICU_ENTRY_POINT_RENAME(u_getVersion)
|
#define u_getVersion U_ICU_ENTRY_POINT_RENAME(u_getVersion)
|
||||||
#define u_get_stdout U_ICU_ENTRY_POINT_RENAME(u_get_stdout)
|
#define u_get_stdout U_ICU_ENTRY_POINT_RENAME(u_get_stdout)
|
||||||
#define u_hasBinaryProperty U_ICU_ENTRY_POINT_RENAME(u_hasBinaryProperty)
|
#define u_hasBinaryProperty U_ICU_ENTRY_POINT_RENAME(u_hasBinaryProperty)
|
||||||
|
#define u_hasIDType U_ICU_ENTRY_POINT_RENAME(u_hasIDType)
|
||||||
#define u_init U_ICU_ENTRY_POINT_RENAME(u_init)
|
#define u_init U_ICU_ENTRY_POINT_RENAME(u_init)
|
||||||
#define u_isIDIgnorable U_ICU_ENTRY_POINT_RENAME(u_isIDIgnorable)
|
#define u_isIDIgnorable U_ICU_ENTRY_POINT_RENAME(u_isIDIgnorable)
|
||||||
#define u_isIDPart U_ICU_ENTRY_POINT_RENAME(u_isIDPart)
|
#define u_isIDPart U_ICU_ENTRY_POINT_RENAME(u_isIDPart)
|
||||||
|
@ -1192,16 +1194,20 @@
|
||||||
#define ulocimp_canonicalize U_ICU_ENTRY_POINT_RENAME(ulocimp_canonicalize)
|
#define ulocimp_canonicalize U_ICU_ENTRY_POINT_RENAME(ulocimp_canonicalize)
|
||||||
#define ulocimp_forLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_forLanguageTag)
|
#define ulocimp_forLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_forLanguageTag)
|
||||||
#define ulocimp_getBaseName U_ICU_ENTRY_POINT_RENAME(ulocimp_getBaseName)
|
#define ulocimp_getBaseName U_ICU_ENTRY_POINT_RENAME(ulocimp_getBaseName)
|
||||||
#define ulocimp_getCountry U_ICU_ENTRY_POINT_RENAME(ulocimp_getCountry)
|
|
||||||
#define ulocimp_getKeywordValue U_ICU_ENTRY_POINT_RENAME(ulocimp_getKeywordValue)
|
#define ulocimp_getKeywordValue U_ICU_ENTRY_POINT_RENAME(ulocimp_getKeywordValue)
|
||||||
#define ulocimp_getKeywords U_ICU_ENTRY_POINT_RENAME(ulocimp_getKeywords)
|
#define ulocimp_getKeywords U_ICU_ENTRY_POINT_RENAME(ulocimp_getKeywords)
|
||||||
#define ulocimp_getKnownCanonicalizedLocaleForTest U_ICU_ENTRY_POINT_RENAME(ulocimp_getKnownCanonicalizedLocaleForTest)
|
#define ulocimp_getKnownCanonicalizedLocaleForTest U_ICU_ENTRY_POINT_RENAME(ulocimp_getKnownCanonicalizedLocaleForTest)
|
||||||
#define ulocimp_getLanguage U_ICU_ENTRY_POINT_RENAME(ulocimp_getLanguage)
|
#define ulocimp_getLanguage U_ICU_ENTRY_POINT_RENAME(ulocimp_getLanguage)
|
||||||
#define ulocimp_getName U_ICU_ENTRY_POINT_RENAME(ulocimp_getName)
|
#define ulocimp_getName U_ICU_ENTRY_POINT_RENAME(ulocimp_getName)
|
||||||
|
#define ulocimp_getParent U_ICU_ENTRY_POINT_RENAME(ulocimp_getParent)
|
||||||
|
#define ulocimp_getRegion U_ICU_ENTRY_POINT_RENAME(ulocimp_getRegion)
|
||||||
#define ulocimp_getRegionForSupplementalData U_ICU_ENTRY_POINT_RENAME(ulocimp_getRegionForSupplementalData)
|
#define ulocimp_getRegionForSupplementalData U_ICU_ENTRY_POINT_RENAME(ulocimp_getRegionForSupplementalData)
|
||||||
#define ulocimp_getScript U_ICU_ENTRY_POINT_RENAME(ulocimp_getScript)
|
#define ulocimp_getScript U_ICU_ENTRY_POINT_RENAME(ulocimp_getScript)
|
||||||
|
#define ulocimp_getSubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_getSubtags)
|
||||||
|
#define ulocimp_getVariant U_ICU_ENTRY_POINT_RENAME(ulocimp_getVariant)
|
||||||
#define ulocimp_isCanonicalizedLocaleForTest U_ICU_ENTRY_POINT_RENAME(ulocimp_isCanonicalizedLocaleForTest)
|
#define ulocimp_isCanonicalizedLocaleForTest U_ICU_ENTRY_POINT_RENAME(ulocimp_isCanonicalizedLocaleForTest)
|
||||||
#define ulocimp_minimizeSubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_minimizeSubtags)
|
#define ulocimp_minimizeSubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_minimizeSubtags)
|
||||||
|
#define ulocimp_setKeywordValue U_ICU_ENTRY_POINT_RENAME(ulocimp_setKeywordValue)
|
||||||
#define ulocimp_toBcpKey U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpKey)
|
#define ulocimp_toBcpKey U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpKey)
|
||||||
#define ulocimp_toBcpType U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpType)
|
#define ulocimp_toBcpType U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpType)
|
||||||
#define ulocimp_toLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_toLanguageTag)
|
#define ulocimp_toLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_toLanguageTag)
|
||||||
|
@ -1800,6 +1806,7 @@
|
||||||
#define usnum_multiplyByPowerOfTen U_ICU_ENTRY_POINT_RENAME(usnum_multiplyByPowerOfTen)
|
#define usnum_multiplyByPowerOfTen U_ICU_ENTRY_POINT_RENAME(usnum_multiplyByPowerOfTen)
|
||||||
#define usnum_openForInt64 U_ICU_ENTRY_POINT_RENAME(usnum_openForInt64)
|
#define usnum_openForInt64 U_ICU_ENTRY_POINT_RENAME(usnum_openForInt64)
|
||||||
#define usnum_roundTo U_ICU_ENTRY_POINT_RENAME(usnum_roundTo)
|
#define usnum_roundTo U_ICU_ENTRY_POINT_RENAME(usnum_roundTo)
|
||||||
|
#define usnum_setMaximumIntegerDigits U_ICU_ENTRY_POINT_RENAME(usnum_setMaximumIntegerDigits)
|
||||||
#define usnum_setMinimumFractionDigits U_ICU_ENTRY_POINT_RENAME(usnum_setMinimumFractionDigits)
|
#define usnum_setMinimumFractionDigits U_ICU_ENTRY_POINT_RENAME(usnum_setMinimumFractionDigits)
|
||||||
#define usnum_setMinimumIntegerDigits U_ICU_ENTRY_POINT_RENAME(usnum_setMinimumIntegerDigits)
|
#define usnum_setMinimumIntegerDigits U_ICU_ENTRY_POINT_RENAME(usnum_setMinimumIntegerDigits)
|
||||||
#define usnum_setSign U_ICU_ENTRY_POINT_RENAME(usnum_setSign)
|
#define usnum_setSign U_ICU_ENTRY_POINT_RENAME(usnum_setSign)
|
||||||
|
|
|
@ -500,6 +500,9 @@ typedef enum UScriptCode {
|
||||||
/** @stable ICU 72 */
|
/** @stable ICU 72 */
|
||||||
USCRIPT_NAG_MUNDARI = 199,/* Nagm */
|
USCRIPT_NAG_MUNDARI = 199,/* Nagm */
|
||||||
|
|
||||||
|
/** @stable ICU 75 */
|
||||||
|
USCRIPT_ARABIC_NASTALIQ = 200, /* Aran */
|
||||||
|
|
||||||
#ifndef U_HIDE_DEPRECATED_API
|
#ifndef U_HIDE_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
* One more than the highest normal UScriptCode value.
|
* One more than the highest normal UScriptCode value.
|
||||||
|
@ -507,7 +510,7 @@ typedef enum UScriptCode {
|
||||||
*
|
*
|
||||||
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
|
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
|
||||||
*/
|
*/
|
||||||
USCRIPT_CODE_LIMIT = 200
|
USCRIPT_CODE_LIMIT = 201
|
||||||
#endif // U_HIDE_DEPRECATED_API
|
#endif // U_HIDE_DEPRECATED_API
|
||||||
} UScriptCode;
|
} UScriptCode;
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,6 @@ enum {
|
||||||
*/
|
*/
|
||||||
USET_ADD_CASE_MAPPINGS = 4,
|
USET_ADD_CASE_MAPPINGS = 4,
|
||||||
|
|
||||||
#ifndef U_HIDE_DRAFT_API
|
|
||||||
/**
|
/**
|
||||||
* Enable case insensitive matching.
|
* Enable case insensitive matching.
|
||||||
* Same as USET_CASE_INSENSITIVE but using only Simple_Case_Folding (scf) mappings,
|
* Same as USET_CASE_INSENSITIVE but using only Simple_Case_Folding (scf) mappings,
|
||||||
|
@ -120,10 +119,9 @@ enum {
|
||||||
* regular expression implementations where only Simple_Case_Folding mappings are used,
|
* regular expression implementations where only Simple_Case_Folding mappings are used,
|
||||||
* such as in ECMAScript (JavaScript) regular expressions.
|
* such as in ECMAScript (JavaScript) regular expressions.
|
||||||
*
|
*
|
||||||
* @draft ICU 73
|
* @stable ICU 73
|
||||||
*/
|
*/
|
||||||
USET_SIMPLE_CASE_INSENSITIVE = 6
|
USET_SIMPLE_CASE_INSENSITIVE = 6
|
||||||
#endif // U_HIDE_DRAFT_API
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue