diff options
author | romankoshelev <romankoshelev@yandex-team.com> | 2024-05-13 11:00:27 +0300 |
---|---|---|
committer | romankoshelev <romankoshelev@yandex-team.com> | 2024-05-13 11:13:05 +0300 |
commit | 5b22fadb0f035a3b82c328e0ae710ad2b92f6eac (patch) | |
tree | e15dc649c79c4fb78f35cd6694dfe9af9bfcc0ad /contrib/libs/icu/common/ulocbuilder.cpp | |
parent | 5946aa7d3cbca62f6bcf074e8a2b9346e7a96af4 (diff) | |
download | ydb-5b22fadb0f035a3b82c328e0ae710ad2b92f6eac.tar.gz |
Update ICU to 75.1
904da4ae1c86fc5542eac7f1cd18d97b72eb8517
Diffstat (limited to 'contrib/libs/icu/common/ulocbuilder.cpp')
-rw-r--r-- | contrib/libs/icu/common/ulocbuilder.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/contrib/libs/icu/common/ulocbuilder.cpp b/contrib/libs/icu/common/ulocbuilder.cpp new file mode 100644 index 0000000000..3b46647362 --- /dev/null +++ b/contrib/libs/icu/common/ulocbuilder.cpp @@ -0,0 +1,151 @@ +// © 2023 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include <utility> + +#include "unicode/bytestream.h" +#include "unicode/localebuilder.h" +#include "unicode/locid.h" +#include "unicode/stringpiece.h" +#include "unicode/umachine.h" +#include "unicode/ulocbuilder.h" +#include "bytesinkutil.h" +#include "cstring.h" +#include "ustr_imp.h" + +using icu::StringPiece; + +#define EXTERNAL(i) (reinterpret_cast<ULocaleBuilder*>(i)) +#define INTERNAL(e) (reinterpret_cast<icu::LocaleBuilder*>(e)) +#define CONST_INTERNAL(e) (reinterpret_cast<const icu::LocaleBuilder*>(e)) + +ULocaleBuilder* ulocbld_open() { + return EXTERNAL(new icu::LocaleBuilder()); +} + +void ulocbld_close(ULocaleBuilder* builder) { + if (builder == nullptr) return; + delete INTERNAL(builder); +} + +void ulocbld_setLocale(ULocaleBuilder* builder, const char* locale, int32_t length) { + if (builder == nullptr) return; + icu::Locale l; + if (length < 0 || locale[length] == '\0') { + l = icu::Locale(locale); + } else { + if (length >= ULOC_FULLNAME_CAPACITY) { + l.setToBogus(); + } else { + // locale is not null termined but Locale API require one. + // Create a null termined version in buf. + char buf[ULOC_FULLNAME_CAPACITY]; + uprv_memcpy(buf, locale, length); + buf[length] = '\0'; + l = icu::Locale(buf); + } + } + INTERNAL(builder)->setLocale(l); +} + +void +ulocbld_adoptULocale(ULocaleBuilder* builder, ULocale* locale) { + if (builder == nullptr) return; + INTERNAL(builder)->setLocale(*(reinterpret_cast<const icu::Locale*>(locale))); + ulocale_close(locale); +} + +#define STRING_PIECE(s, l) ((l)<0 ? StringPiece(s) : StringPiece((s), (l))) + +#define IMPL_ULOCBLD_SETTER(N) \ +void ulocbld_##N(ULocaleBuilder* bld, const char* s, int32_t l) { \ + if (bld == nullptr) return; \ + INTERNAL(bld)->N(STRING_PIECE(s,l)); \ +} + +IMPL_ULOCBLD_SETTER(setLanguageTag) +IMPL_ULOCBLD_SETTER(setLanguage) +IMPL_ULOCBLD_SETTER(setScript) +IMPL_ULOCBLD_SETTER(setRegion) +IMPL_ULOCBLD_SETTER(setVariant) +IMPL_ULOCBLD_SETTER(addUnicodeLocaleAttribute) +IMPL_ULOCBLD_SETTER(removeUnicodeLocaleAttribute) + +void ulocbld_setExtension(ULocaleBuilder* builder, char key, const char* value, int32_t length) { + if (builder == nullptr) return; + INTERNAL(builder)->setExtension(key, STRING_PIECE(value, length)); +} + +void ulocbld_setUnicodeLocaleKeyword( + ULocaleBuilder* builder, const char* key, int32_t keyLength, + const char* type, int32_t typeLength) { + if (builder == nullptr) return; + INTERNAL(builder)->setUnicodeLocaleKeyword( + STRING_PIECE(key, keyLength), STRING_PIECE(type, typeLength)); +} + +void ulocbld_clear(ULocaleBuilder* builder) { + if (builder == nullptr) return; + INTERNAL(builder)->clear(); +} + +void ulocbld_clearExtensions(ULocaleBuilder* builder) { + if (builder == nullptr) return; + INTERNAL(builder)->clearExtensions(); +} + + +ULocale* ulocbld_buildULocale(ULocaleBuilder* builder, UErrorCode* err) { + if (builder == nullptr) { + *err = U_ILLEGAL_ARGUMENT_ERROR; + return nullptr; + } + icu::Locale l = INTERNAL(builder)->build(*err); + if (U_FAILURE(*err)) return nullptr; + icu::Locale* r = l.clone(); + if (r == nullptr) { + *err = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + return reinterpret_cast<ULocale*>(r); +} + +int32_t ulocbld_buildLocaleID(ULocaleBuilder* builder, + char* buffer, int32_t bufferCapacity, UErrorCode* err) { + if (U_FAILURE(*err)) { return 0; } + if (builder == nullptr) { + *err = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + icu::Locale l = INTERNAL(builder)->build(*err); + if (U_FAILURE(*err)) { return 0; } + int32_t length = (int32_t)(uprv_strlen(l.getName())); + if (0 < length && length <= bufferCapacity) { + uprv_memcpy(buffer, l.getName(), length); + } + return u_terminateChars(buffer, bufferCapacity, length, err); +} + +int32_t ulocbld_buildLanguageTag(ULocaleBuilder* builder, + char* buffer, int32_t bufferCapacity, UErrorCode* err) { + if (U_FAILURE(*err)) { return 0; } + if (builder == nullptr) { + *err = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + icu::Locale l = INTERNAL(builder)->build(*err); + return icu::ByteSinkUtil::viaByteSinkToTerminatedChars( + buffer, bufferCapacity, + [&](icu::ByteSink& sink, UErrorCode& status) { + l.toLanguageTag(sink, status); + }, + *err); +} + +UBool ulocbld_copyErrorTo(const ULocaleBuilder* builder, UErrorCode *outErrorCode) { + if (builder == nullptr) { + *outErrorCode = U_ILLEGAL_ARGUMENT_ERROR; + return true; + } + return CONST_INTERNAL(builder)->copyErrorTo(*outErrorCode); +} |