[Intl] Add ResourceBundle and RelativeDateTimeFormatter to GetAvailableLocales

R=bstell@chromium.org, cira@chromium.org, yangguo@chromium.org

Bug: v8:7869
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ia7176016ecd6da317b3b0eb7af7bf482f99c8129
Reviewed-on: https://chromium-review.googlesource.com/1121657
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Jungshik Shin <jshin@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54382}
This commit is contained in:
Frank Tang 2018-07-10 12:29:55 -07:00 committed by Commit Bot
parent 652acb782d
commit f8036e0a28
3 changed files with 48 additions and 2 deletions

View File

@ -28,7 +28,9 @@ enum class IcuService {
kCollator,
kDateFormat,
kNumberFormat,
kPluralRules
kPluralRules,
kResourceBundle,
kRelativeDateTimeFormatter
};
const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat,

View File

@ -42,6 +42,7 @@
#include "unicode/ucurr.h"
#include "unicode/unum.h"
#include "unicode/upluralrules.h"
#include "unicode/ures.h"
#include "unicode/uvernum.h"
#include "unicode/uversion.h"
@ -1103,6 +1104,7 @@ bool Intl::RemoveLocaleScriptTag(const std::string& icu_locale,
std::set<std::string> Intl::GetAvailableLocales(const IcuService& service) {
const icu::Locale* icu_available_locales = nullptr;
int32_t count = 0;
std::set<std::string> locales;
switch (service) {
case IcuService::kBreakIterator:
@ -1125,12 +1127,48 @@ std::set<std::string> Intl::GetAvailableLocales(const IcuService& service) {
// https://ssl.icu-project.org/trac/ticket/12756
icu_available_locales = icu::Locale::getAvailableLocales(count);
break;
case IcuService::kResourceBundle: {
UErrorCode status = U_ZERO_ERROR;
UEnumeration* en = ures_openAvailableLocales(nullptr, &status);
int32_t length = 0;
const char* locale_str = uenum_next(en, &length, &status);
while (U_SUCCESS(status) && (locale_str != nullptr)) {
std::string locale(locale_str, length);
std::replace(locale.begin(), locale.end(), '_', '-');
locales.insert(locale);
std::string shortened_locale;
if (Intl::RemoveLocaleScriptTag(locale_str, &shortened_locale)) {
std::replace(shortened_locale.begin(), shortened_locale.end(), '_',
'-');
locales.insert(shortened_locale);
}
locale_str = uenum_next(en, &length, &status);
}
uenum_close(en);
return locales;
}
case IcuService::kRelativeDateTimeFormatter: {
// ICU RelativeDateTimeFormatter does not provide a getAvailableLocales()
// interface, because RelativeDateTimeFormatter depends on
// 1. NumberFormat and 2. ResourceBundle, return the
// intersection of these two set.
// ICU FR at https://unicode-org.atlassian.net/browse/ICU-20009
// TODO(ftang): change to call ICU's getAvailableLocales() after it is
// added.
std::set<std::string> number_format_set(
Intl::GetAvailableLocales(IcuService::kNumberFormat));
std::set<std::string> resource_bundle_set(
Intl::GetAvailableLocales(IcuService::kResourceBundle));
set_intersection(resource_bundle_set.begin(), resource_bundle_set.end(),
number_format_set.begin(), number_format_set.end(),
std::inserter(locales, locales.begin()));
return locales;
}
}
UErrorCode error = U_ZERO_ERROR;
char result[ULOC_FULLNAME_CAPACITY];
std::set<std::string> locales;
for (int32_t i = 0; i < count; ++i) {
const char* icu_name = icu_available_locales[i].getName();

View File

@ -248,6 +248,12 @@ TEST(GetAvailableLocales) {
locales = Intl::GetAvailableLocales(IcuService::kPluralRules);
CHECK(locales.count("en-US"));
locales = Intl::GetAvailableLocales(IcuService::kResourceBundle);
CHECK(locales.count("en-US"));
locales = Intl::GetAvailableLocales(IcuService::kRelativeDateTimeFormatter);
CHECK(locales.count("en-US"));
}
TEST(IsObjectOfType) {