ulocale.cpp (3237B)
1 // © 2023 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 // 4 #include "unicode/bytestream.h" 5 #include "unicode/errorcode.h" 6 #include "unicode/stringpiece.h" 7 #include "unicode/utypes.h" 8 #include "unicode/ustring.h" 9 #include "unicode/ulocale.h" 10 #include "unicode/locid.h" 11 12 #include "bytesinkutil.h" 13 #include "cmemory.h" 14 15 U_NAMESPACE_USE 16 #define EXTERNAL(i) (reinterpret_cast<ULocale*>(i)) 17 #define CONST_INTERNAL(e) (reinterpret_cast<const icu::Locale*>(e)) 18 #define INTERNAL(e) (reinterpret_cast<icu::Locale*>(e)) 19 20 ULocale* 21 ulocale_openForLocaleID(const char* localeID, int32_t length, UErrorCode* err) { 22 if (U_FAILURE(*err)) { return nullptr; } 23 if (length < 0) { 24 return EXTERNAL(icu::Locale::createFromName(localeID).clone()); 25 } 26 return EXTERNAL(icu::Locale::createFromName(StringPiece{localeID, length}).clone()); 27 } 28 29 ULocale* 30 ulocale_openForLanguageTag(const char* tag, int32_t length, UErrorCode* err) { 31 if (U_FAILURE(*err)) { return nullptr; } 32 Locale l = icu::Locale::forLanguageTag(length < 0 ? StringPiece(tag) : StringPiece(tag, length), *err); 33 if (U_FAILURE(*err)) { return nullptr; } 34 return EXTERNAL(l.clone()); 35 } 36 37 void 38 ulocale_close(ULocale* locale) { 39 delete INTERNAL(locale); 40 } 41 42 #define IMPL_ULOCALE_STRING_GETTER(N1, N2) \ 43 const char* ulocale_get ## N1(const ULocale* locale) { \ 44 if (locale == nullptr) return nullptr; \ 45 return CONST_INTERNAL(locale)->get ## N2(); \ 46 } 47 48 #define IMPL_ULOCALE_STRING_IDENTICAL_GETTER(N) IMPL_ULOCALE_STRING_GETTER(N, N) 49 50 #define IMPL_ULOCALE_GET_KEYWORD_VALUE(N) \ 51 int32_t ulocale_get ##N ( \ 52 const ULocale* locale, const char* keyword, int32_t keywordLength, \ 53 char* valueBuffer, int32_t bufferCapacity, UErrorCode *err) { \ 54 if (U_FAILURE(*err)) return 0; \ 55 if (locale == nullptr) { \ 56 *err = U_ILLEGAL_ARGUMENT_ERROR; \ 57 return 0; \ 58 } \ 59 return ByteSinkUtil::viaByteSinkToTerminatedChars( \ 60 valueBuffer, bufferCapacity, \ 61 [&](ByteSink& sink, UErrorCode& status) { \ 62 CONST_INTERNAL(locale)->get ## N( \ 63 keywordLength < 0 ? StringPiece(keyword) : StringPiece(keyword, keywordLength), \ 64 sink, status); \ 65 }, \ 66 *err); \ 67 } 68 69 #define IMPL_ULOCALE_GET_KEYWORDS(N) \ 70 UEnumeration* ulocale_get ## N(const ULocale* locale, UErrorCode *err) { \ 71 if (U_FAILURE(*err)) return nullptr; \ 72 if (locale == nullptr) { \ 73 *err = U_ILLEGAL_ARGUMENT_ERROR; \ 74 return nullptr; \ 75 } \ 76 return uenum_openFromStringEnumeration( \ 77 CONST_INTERNAL(locale)->create ## N(*err), err); \ 78 } 79 80 IMPL_ULOCALE_STRING_IDENTICAL_GETTER(Language) 81 IMPL_ULOCALE_STRING_IDENTICAL_GETTER(Script) 82 IMPL_ULOCALE_STRING_GETTER(Region, Country) 83 IMPL_ULOCALE_STRING_IDENTICAL_GETTER(Variant) 84 IMPL_ULOCALE_STRING_GETTER(LocaleID, Name) 85 IMPL_ULOCALE_STRING_IDENTICAL_GETTER(BaseName) 86 IMPL_ULOCALE_GET_KEYWORD_VALUE(KeywordValue) 87 IMPL_ULOCALE_GET_KEYWORD_VALUE(UnicodeKeywordValue) 88 IMPL_ULOCALE_GET_KEYWORDS(Keywords) 89 IMPL_ULOCALE_GET_KEYWORDS(UnicodeKeywords) 90 91 bool ulocale_isBogus(const ULocale* locale) { 92 if (locale == nullptr) return false; 93 return CONST_INTERNAL(locale)->isBogus(); 94 } 95 96 /*eof*/