uprv_free(keywords);
}
+// A wrapper around KeywordEnumeration that calls uloc_toUnicodeLocaleKey() in
+// the next() method for each keyword before returning it.
+class UnicodeKeywordEnumeration : public KeywordEnumeration {
+public:
+ using KeywordEnumeration::KeywordEnumeration;
+ virtual ~UnicodeKeywordEnumeration() = default;
+
+ virtual const char* next(int32_t* resultLength, UErrorCode& status) {
+ const char* legacy_key = KeywordEnumeration::next(nullptr, status);
+ if (U_SUCCESS(status) && legacy_key != nullptr) {
+ const char* key = uloc_toUnicodeLocaleKey(legacy_key);
+ if (key == nullptr) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ } else {
+ if (resultLength != nullptr) *resultLength = uprv_strlen(key);
+ return key;
+ }
+ }
+ if (resultLength != nullptr) *resultLength = 0;
+ return nullptr;
+ }
+};
+
StringEnumeration *
Locale::createKeywords(UErrorCode &status) const
{
return result;
}
+StringEnumeration *
+Locale::createUnicodeKeywords(UErrorCode &status) const
+{
+ char keywords[256];
+ int32_t keywordCapacity = 256;
+ StringEnumeration *result = NULL;
+
+ const char* variantStart = uprv_strchr(fullName, '@');
+ const char* assignment = uprv_strchr(fullName, '=');
+ if(variantStart) {
+ if(assignment > variantStart) {
+ int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
+ if(keyLen) {
+ result = new UnicodeKeywordEnumeration(keywords, keyLen, 0, status);
+ }
+ } else {
+ status = U_INVALID_FORMAT_ERROR;
+ }
+ }
+ return result;
+}
+
int32_t
Locale::getKeywordValue(const char* keywordName, char *buffer, int32_t bufLen, UErrorCode &status) const
{
********************************************************************/
#include "loctest.h"
+#include "unicode/localpointer.h"
#include "unicode/decimfmt.h"
#include "unicode/ucurr.h"
#include "unicode/smpdtfmt.h"
TESTCASE_AUTO(TestSetIsBogus);
TESTCASE_AUTO(TestParallelAPIValues);
TESTCASE_AUTO(TestKeywordVariants);
+ TESTCASE_AUTO(TestCreateUnicodeKeywords);
TESTCASE_AUTO(TestKeywordVariantParsing);
TESTCASE_AUTO(TestSetKeywordValue);
TESTCASE_AUTO(TestGetBaseName);
}
+
+void
+LocaleTest::TestCreateUnicodeKeywords(void) {
+ IcuTestErrorCode status(*this, "TestCreateUnicodeKeywords()");
+
+ static const Locale l("de@calendar=buddhist;collation=phonebook");
+
+ LocalPointer<StringEnumeration> keys(l.createUnicodeKeywords(status));
+ status.errIfFailureAndReset("\"%s\"", l.getName());
+
+ const char* key;
+ int32_t resultLength;
+
+ key = keys->next(&resultLength, status);
+ status.errIfFailureAndReset("key #1");
+ assertEquals("resultLength", 2, resultLength);
+ assertTrue("key != nullptr", key != nullptr);
+ assertEquals("calendar", "ca", key);
+
+ key = keys->next(&resultLength, status);
+ status.errIfFailureAndReset("key #2");
+ assertEquals("resultLength", 2, resultLength);
+ assertTrue("key != nullptr", key != nullptr);
+ assertEquals("collation", "co", key);
+
+ key = keys->next(&resultLength, status);
+ status.errIfFailureAndReset("end of keys");
+ assertEquals("resultLength", 0, resultLength);
+ assertTrue("key == nullptr", key == nullptr);
+
+ const UnicodeString* skey;
+ keys->reset(status); // KeywordEnumeration::reset() never touches status.
+
+ skey = keys->snext(status);
+ status.errIfFailureAndReset("skey #1");
+ assertTrue("skey != nullptr", skey != nullptr);
+ assertEquals("calendar", "ca", *skey);
+
+ skey = keys->snext(status);
+ status.errIfFailureAndReset("skey #2");
+ assertTrue("skey != nullptr", skey != nullptr);
+ assertEquals("collation", "co", *skey);
+
+ skey = keys->snext(status);
+ status.errIfFailureAndReset("end of keys");
+ assertTrue("skey == nullptr", skey == nullptr);
+}
+
+
void
LocaleTest::TestKeywordVariantParsing(void) {
static const struct {