diff options
Diffstat (limited to 'thirdparty/icu4c/common/ulocale.cpp')
-rw-r--r-- | thirdparty/icu4c/common/ulocale.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/thirdparty/icu4c/common/ulocale.cpp b/thirdparty/icu4c/common/ulocale.cpp new file mode 100644 index 0000000000..471ef0ce79 --- /dev/null +++ b/thirdparty/icu4c/common/ulocale.cpp @@ -0,0 +1,99 @@ +// © 2023 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +// +#include "unicode/errorcode.h" +#include "unicode/stringpiece.h" +#include "unicode/utypes.h" +#include "unicode/ustring.h" +#include "unicode/ulocale.h" +#include "unicode/locid.h" + +#include "charstr.h" +#include "cmemory.h" +#include "ustr_imp.h" + +U_NAMESPACE_USE +#define EXTERNAL(i) (reinterpret_cast<ULocale*>(i)) +#define CONST_INTERNAL(e) (reinterpret_cast<const icu::Locale*>(e)) +#define INTERNAL(e) (reinterpret_cast<icu::Locale*>(e)) + +ULocale* +ulocale_openForLocaleID(const char* localeID, int32_t length, UErrorCode* err) { + CharString str(length < 0 ? StringPiece(localeID) : StringPiece(localeID, length), *err); + if (U_FAILURE(*err)) return nullptr; + return EXTERNAL(icu::Locale::createFromName(str.data()).clone()); +} + +ULocale* +ulocale_openForLanguageTag(const char* tag, int32_t length, UErrorCode* err) { + Locale l = icu::Locale::forLanguageTag(length < 0 ? StringPiece(tag) : StringPiece(tag, length), *err); + if (U_FAILURE(*err)) return nullptr; + return EXTERNAL(l.clone()); +} + +void +ulocale_close(ULocale* locale) { + delete INTERNAL(locale); +} + +#define IMPL_ULOCALE_STRING_GETTER(N1, N2) \ +const char* ulocale_get ## N1(const ULocale* locale) { \ + if (locale == nullptr) return nullptr; \ + return CONST_INTERNAL(locale)->get ## N2(); \ +} + +#define IMPL_ULOCALE_STRING_IDENTICAL_GETTER(N) IMPL_ULOCALE_STRING_GETTER(N, N) + +#define IMPL_ULOCALE_GET_KEYWORD_VALUE(N) \ +int32_t ulocale_get ##N ( \ + const ULocale* locale, const char* keyword, int32_t keywordLength, \ + char* valueBuffer, int32_t bufferCapacity, UErrorCode *err) { \ + if (U_FAILURE(*err)) return 0; \ + if (locale == nullptr) { \ + *err = U_ILLEGAL_ARGUMENT_ERROR; \ + return 0; \ + } \ + CheckedArrayByteSink sink(valueBuffer, bufferCapacity); \ + CONST_INTERNAL(locale)->get ## N( \ + keywordLength < 0 ? StringPiece(keyword) : StringPiece(keyword, keywordLength), \ + sink, *err); \ + int32_t reslen = sink.NumberOfBytesAppended(); \ + if (U_FAILURE(*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) \ +UEnumeration* ulocale_get ## N(const ULocale* locale, UErrorCode *err) { \ + if (U_FAILURE(*err)) return nullptr; \ + if (locale == nullptr) { \ + *err = U_ILLEGAL_ARGUMENT_ERROR; \ + return nullptr; \ + } \ + return uenum_openFromStringEnumeration( \ + CONST_INTERNAL(locale)->create ## N(*err), err); \ +} + +IMPL_ULOCALE_STRING_IDENTICAL_GETTER(Language) +IMPL_ULOCALE_STRING_IDENTICAL_GETTER(Script) +IMPL_ULOCALE_STRING_GETTER(Region, Country) +IMPL_ULOCALE_STRING_IDENTICAL_GETTER(Variant) +IMPL_ULOCALE_STRING_GETTER(LocaleID, Name) +IMPL_ULOCALE_STRING_IDENTICAL_GETTER(BaseName) +IMPL_ULOCALE_GET_KEYWORD_VALUE(KeywordValue) +IMPL_ULOCALE_GET_KEYWORD_VALUE(UnicodeKeywordValue) +IMPL_ULOCALE_GET_KEYWORDS(Keywords) +IMPL_ULOCALE_GET_KEYWORDS(UnicodeKeywords) + +bool ulocale_isBogus(const ULocale* locale) { + if (locale == nullptr) return false; + return CONST_INTERNAL(locale)->isBogus(); +} + +/*eof*/ |