Commit 8f8d11a2 authored by jdoerrie's avatar jdoerrie Committed by Commit Bot

[base] Cleanup base::win::i18n and prepare for string16 Switch

This change prepares base::win::i18n for the base::string16 switch and
cleans up LanguageSelectors' interface and implementation by e.g.
replacing a pair of pointers with a base::span.

Bug: 911896
Change-Id: If02538532908c1ea1e92044fc9f37176c085f3f5
Reviewed-on: https://chromium-review.googlesource.com/c/1437210
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Commit-Queue: Roger Tawa <rogerta@chromium.org>
Auto-Submit: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarRoger Tawa <rogerta@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#626663}
parent 65871083
This diff is collapsed.
...@@ -8,11 +8,14 @@ ...@@ -8,11 +8,14 @@
#ifndef BASE_WIN_EMBEDDED_I18N_LANGUAGE_SELECTOR_H_ #ifndef BASE_WIN_EMBEDDED_I18N_LANGUAGE_SELECTOR_H_
#define BASE_WIN_EMBEDDED_I18N_LANGUAGE_SELECTOR_H_ #define BASE_WIN_EMBEDDED_I18N_LANGUAGE_SELECTOR_H_
#include <utility>
#include <vector> #include <vector>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/containers/span.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/string_piece.h"
namespace base { namespace base {
namespace win { namespace win {
...@@ -23,10 +26,7 @@ namespace i18n { ...@@ -23,10 +26,7 @@ namespace i18n {
// override selection should a corresponding translation be available. // override selection should a corresponding translation be available.
class BASE_EXPORT LanguageSelector { class BASE_EXPORT LanguageSelector {
public: public:
struct LangToOffset { using LangToOffset = std::pair<base::StringPiece16, int>;
const wchar_t* language;
int offset;
};
// Constructor to be used for users of this class that will provide the actual // Constructor to be used for users of this class that will provide the actual
// language offsets that will be used. // language offsets that will be used.
...@@ -36,9 +36,8 @@ class BASE_EXPORT LanguageSelector { ...@@ -36,9 +36,8 @@ class BASE_EXPORT LanguageSelector {
// |languages_to_offset_begin| and |languages_to_offset_end| point to a sorted // |languages_to_offset_begin| and |languages_to_offset_end| point to a sorted
// array of language identifiers (and their offsets) for which translations // array of language identifiers (and their offsets) for which translations
// are available. // are available.
LanguageSelector(const base::string16& preferred_language, LanguageSelector(base::StringPiece16 preferred_language,
const LangToOffset* languages_to_offset_begin, base::span<const LangToOffset> languages_to_offset);
const LangToOffset* languages_to_offset_end);
// Constructor for testing purposes. // Constructor for testing purposes.
// |candidates| is a list of all candiate languages that can be used to // |candidates| is a list of all candiate languages that can be used to
...@@ -47,8 +46,7 @@ class BASE_EXPORT LanguageSelector { ...@@ -47,8 +46,7 @@ class BASE_EXPORT LanguageSelector {
// array of language identifiers (and their offsets) for which translations // array of language identifiers (and their offsets) for which translations
// are available. // are available.
LanguageSelector(const std::vector<base::string16>& candidates, LanguageSelector(const std::vector<base::string16>& candidates,
const LangToOffset* languages_to_offset_begin, base::span<const LangToOffset> languages_to_offset);
const LangToOffset* languages_to_offset_end);
~LanguageSelector(); ~LanguageSelector();
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
namespace { namespace {
...@@ -86,25 +88,26 @@ bool GetMUIPreferredUILanguageList(LanguageFunction function, ULONG flags, ...@@ -86,25 +88,26 @@ bool GetMUIPreferredUILanguageList(LanguageFunction function, ULONG flags,
return false; return false;
} }
bool GetUserDefaultUILanguage(std::wstring* language, std::wstring* region) { bool GetUserDefaultUILanguage(base::string16* language,
base::string16* region) {
DCHECK(language); DCHECK(language);
LANGID lang_id = ::GetUserDefaultUILanguage(); LANGID lang_id = ::GetUserDefaultUILanguage();
if (LOCALE_CUSTOM_UI_DEFAULT != lang_id) { if (LOCALE_CUSTOM_UI_DEFAULT != lang_id) {
const LCID locale_id = MAKELCID(lang_id, SORT_DEFAULT); const LCID locale_id = MAKELCID(lang_id, SORT_DEFAULT);
// max size for LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME is 9 // max size for LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME is 9
wchar_t result_buffer[9]; base::char16 result_buffer[9];
int result_length = int result_length =
GetLocaleInfo(locale_id, LOCALE_SISO639LANGNAME, &result_buffer[0], GetLocaleInfo(locale_id, LOCALE_SISO639LANGNAME,
base::size(result_buffer)); base::wdata(result_buffer), base::size(result_buffer));
DPCHECK(0 != result_length) << "Failed getting language id"; DPCHECK(0 != result_length) << "Failed getting language id";
if (1 < result_length) { if (1 < result_length) {
language->assign(&result_buffer[0], result_length - 1); language->assign(&result_buffer[0], result_length - 1);
region->clear(); region->clear();
if (SUBLANG_NEUTRAL != SUBLANGID(lang_id)) { if (SUBLANG_NEUTRAL != SUBLANGID(lang_id)) {
result_length = result_length = GetLocaleInfo(locale_id, LOCALE_SISO3166CTRYNAME,
GetLocaleInfo(locale_id, LOCALE_SISO3166CTRYNAME, &result_buffer[0], base::wdata(result_buffer),
base::size(result_buffer)); base::size(result_buffer));
DPCHECK(0 != result_length) << "Failed getting region id"; DPCHECK(0 != result_length) << "Failed getting region id";
if (1 < result_length) if (1 < result_length)
region->assign(&result_buffer[0], result_length - 1); region->assign(&result_buffer[0], result_length - 1);
...@@ -119,27 +122,26 @@ bool GetUserDefaultUILanguage(std::wstring* language, std::wstring* region) { ...@@ -119,27 +122,26 @@ bool GetUserDefaultUILanguage(std::wstring* language, std::wstring* region) {
return false; return false;
} }
bool GetPreferredUILanguageList(LanguageFunction function, ULONG flags, bool GetPreferredUILanguageList(LanguageFunction function,
std::vector<std::wstring>* languages) { ULONG flags,
std::vector<base::string16>* languages) {
std::vector<wchar_t> buffer; std::vector<wchar_t> buffer;
std::wstring language; base::string16 language;
std::wstring region; base::string16 region;
if (GetMUIPreferredUILanguageList(function, flags, &buffer)) { if (GetMUIPreferredUILanguageList(function, flags, &buffer)) {
std::vector<wchar_t>::const_iterator scan = buffer.begin(); std::vector<wchar_t>::const_iterator scan = buffer.begin();
language.assign(&*scan); language = base::WideToUTF16(&*scan);
while (!language.empty()) { while (!language.empty()) {
languages->push_back(language); languages->push_back(language);
scan += language.size() + 1; scan += language.size() + 1;
language.assign(&*scan); language = base::WideToUTF16(&*scan);
} }
} else if (GetUserDefaultUILanguage(&language, &region)) { } else if (GetUserDefaultUILanguage(&language, &region)) {
// Mimic the MUI behavior of putting the neutral version of the lang after // Mimic the MUI behavior of putting the neutral version of the lang after
// the regional one (e.g., "fr-CA, fr"). // the regional one (e.g., "fr-CA, fr").
if (!region.empty()) if (!region.empty())
languages->push_back(std::wstring(language) languages->push_back(language + base::string16(1, '-') + region);
.append(1, L'-')
.append(region));
languages->push_back(language); languages->push_back(language);
} else { } else {
return false; return false;
...@@ -154,12 +156,12 @@ namespace base { ...@@ -154,12 +156,12 @@ namespace base {
namespace win { namespace win {
namespace i18n { namespace i18n {
bool GetUserPreferredUILanguageList(std::vector<std::wstring>* languages) { bool GetUserPreferredUILanguageList(std::vector<base::string16>* languages) {
DCHECK(languages); DCHECK(languages);
return GetPreferredUILanguageList(USER_LANGUAGES, 0, languages); return GetPreferredUILanguageList(USER_LANGUAGES, 0, languages);
} }
bool GetThreadPreferredUILanguageList(std::vector<std::wstring>* languages) { bool GetThreadPreferredUILanguageList(std::vector<base::string16>* languages) {
DCHECK(languages); DCHECK(languages);
return GetPreferredUILanguageList( return GetPreferredUILanguageList(
THREAD_LANGUAGES, MUI_MERGE_SYSTEM_FALLBACK | MUI_MERGE_USER_FALLBACK, THREAD_LANGUAGES, MUI_MERGE_SYSTEM_FALLBACK | MUI_MERGE_USER_FALLBACK,
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
#ifndef BASE_WIN_I18N_H_ #ifndef BASE_WIN_I18N_H_
#define BASE_WIN_I18N_H_ #define BASE_WIN_I18N_H_
#include <string>
#include <vector> #include <vector>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/strings/string16.h"
namespace base { namespace base {
namespace win { namespace win {
...@@ -18,13 +18,13 @@ namespace i18n { ...@@ -18,13 +18,13 @@ namespace i18n {
// available, falling-back on the user default UI language otherwise. Returns // available, falling-back on the user default UI language otherwise. Returns
// true if at least one language is added. // true if at least one language is added.
BASE_EXPORT bool GetUserPreferredUILanguageList( BASE_EXPORT bool GetUserPreferredUILanguageList(
std::vector<std::wstring>* languages); std::vector<base::string16>* languages);
// Adds to |languages| the list of thread, process, user, and system preferred // Adds to |languages| the list of thread, process, user, and system preferred
// UI languages from MUI, if available, falling-back on the user default UI // UI languages from MUI, if available, falling-back on the user default UI
// language otherwise. Returns true if at least one language is added. // language otherwise. Returns true if at least one language is added.
BASE_EXPORT bool GetThreadPreferredUILanguageList( BASE_EXPORT bool GetThreadPreferredUILanguageList(
std::vector<std::wstring>* languages); std::vector<base::string16>* languages);
} // namespace i18n } // namespace i18n
} // namespace win } // namespace win
......
...@@ -17,25 +17,21 @@ namespace i18n { ...@@ -17,25 +17,21 @@ namespace i18n {
// Tests that at least one user preferred UI language can be obtained. // Tests that at least one user preferred UI language can be obtained.
TEST(I18NTest, GetUserPreferredUILanguageList) { TEST(I18NTest, GetUserPreferredUILanguageList) {
std::vector<std::wstring> languages; std::vector<base::string16> languages;
EXPECT_TRUE(GetUserPreferredUILanguageList(&languages)); EXPECT_TRUE(GetUserPreferredUILanguageList(&languages));
EXPECT_NE(static_cast<std::vector<std::wstring>::size_type>(0), EXPECT_FALSE(languages.empty());
languages.size()); for (const auto& language : languages) {
for (std::vector<std::wstring>::const_iterator scan = languages.begin(), EXPECT_FALSE(language.empty());
end = languages.end(); scan != end; ++scan) {
EXPECT_FALSE((*scan).empty());
} }
} }
// Tests that at least one thread preferred UI language can be obtained. // Tests that at least one thread preferred UI language can be obtained.
TEST(I18NTest, GetThreadPreferredUILanguageList) { TEST(I18NTest, GetThreadPreferredUILanguageList) {
std::vector<std::wstring> languages; std::vector<base::string16> languages;
EXPECT_TRUE(GetThreadPreferredUILanguageList(&languages)); EXPECT_TRUE(GetThreadPreferredUILanguageList(&languages));
EXPECT_NE(static_cast<std::vector<std::wstring>::size_type>(0), EXPECT_FALSE(languages.empty());
languages.size()); for (const auto& language : languages) {
for (std::vector<std::wstring>::const_iterator scan = languages.begin(), EXPECT_FALSE(language.empty());
end = languages.end(); scan != end; ++scan) {
EXPECT_FALSE((*scan).empty());
} }
} }
......
...@@ -82,9 +82,7 @@ base::FilePath GetStartupSentinelLocation() { ...@@ -82,9 +82,7 @@ base::FilePath GetStartupSentinelLocation() {
const base::win::i18n::LanguageSelector& GetLanguageSelector() { const base::win::i18n::LanguageSelector& GetLanguageSelector() {
static base::NoDestructor<base::win::i18n::LanguageSelector> instance( static base::NoDestructor<base::win::i18n::LanguageSelector> instance(
base::string16(), &kLanguageOffsetPairs[0], base::string16(), kLanguageOffsetPairs);
&kLanguageOffsetPairs[base::size(kLanguageOffsetPairs)]);
return *instance; return *instance;
} }
......
...@@ -45,9 +45,7 @@ base::string16 GetPreferredLanguageFromGoogleUpdate() { ...@@ -45,9 +45,7 @@ base::string16 GetPreferredLanguageFromGoogleUpdate() {
const base::win::i18n::LanguageSelector& GetLanguageSelector() { const base::win::i18n::LanguageSelector& GetLanguageSelector() {
static base::NoDestructor<base::win::i18n::LanguageSelector> instance( static base::NoDestructor<base::win::i18n::LanguageSelector> instance(
GetPreferredLanguageFromGoogleUpdate(), &kLanguageOffsetPairs[0], GetPreferredLanguageFromGoogleUpdate(), kLanguageOffsetPairs);
&kLanguageOffsetPairs[base::size(kLanguageOffsetPairs)]);
return *instance; return *instance;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment