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