100 lines
3.2 KiB
C++
100 lines
3.2 KiB
C++
// © 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*/
|