OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "app/l10n_util.h" | 5 #include "app/l10n_util.h" |
6 | 6 |
7 #if defined(TOOLKIT_USES_GTK) | 7 #if defined(TOOLKIT_USES_GTK) |
8 #include <glib/gutils.h> | 8 #include <glib/gutils.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "base/path_service.h" | 22 #include "base/path_service.h" |
23 #include "base/scoped_ptr.h" | 23 #include "base/scoped_ptr.h" |
24 #include "base/string16.h" | 24 #include "base/string16.h" |
25 #include "base/string_number_conversions.h" | 25 #include "base/string_number_conversions.h" |
26 #include "base/string_split.h" | 26 #include "base/string_split.h" |
27 #include "base/sys_string_conversions.h" | 27 #include "base/sys_string_conversions.h" |
28 #include "base/utf_string_conversions.h" | 28 #include "base/utf_string_conversions.h" |
29 #include "build/build_config.h" | 29 #include "build/build_config.h" |
30 #include "gfx/canvas.h" | 30 #include "gfx/canvas.h" |
31 #include "unicode/rbbi.h" | 31 #include "unicode/rbbi.h" |
32 #include "unicode/uloc.h" | |
32 | 33 |
33 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
34 #include "app/l10n_util_mac.h" | 35 #include "app/l10n_util_mac.h" |
35 #elif defined(OS_WIN) | 36 #elif defined(OS_WIN) |
36 #include "app/l10n_util_win.h" | 37 #include "app/l10n_util_win.h" |
37 #endif | 38 #endif |
38 | 39 |
39 namespace { | 40 namespace { |
40 | 41 |
41 #if defined(OS_WIN) | 42 #if defined(OS_WIN) |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 display_locale.c_str(), | 472 display_locale.c_str(), |
472 WriteInto(&display_name, buffer_size + 1), buffer_size, &error); | 473 WriteInto(&display_name, buffer_size + 1), buffer_size, &error); |
473 DCHECK(U_SUCCESS(error)); | 474 DCHECK(U_SUCCESS(error)); |
474 display_name.resize(actual_size); | 475 display_name.resize(actual_size); |
475 // Add an RTL mark so parentheses are properly placed. | 476 // Add an RTL mark so parentheses are properly placed. |
476 if (is_for_ui && base::i18n::IsRTL()) | 477 if (is_for_ui && base::i18n::IsRTL()) |
477 display_name.push_back(static_cast<char16>(base::i18n::kRightToLeftMark)); | 478 display_name.push_back(static_cast<char16>(base::i18n::kRightToLeftMark)); |
478 return display_name; | 479 return display_name; |
479 } | 480 } |
480 | 481 |
482 std::string NormalizeLocale(const std::string& locale) { | |
483 std::string normalized_locale(locale); | |
484 std::replace(normalized_locale.begin(), normalized_locale.end(), '-', '_'); | |
485 | |
486 return normalized_locale; | |
487 } | |
488 | |
489 void GetParentLocales(const std::string& current_locale, | |
490 std::vector<std::string>* parent_locales) { | |
491 std::string locale(NormalizeLocale(current_locale)); | |
492 | |
493 const int kNameCapacity = 256; | |
494 char parent[kNameCapacity]; | |
495 base::strlcpy(parent, locale.c_str(), kNameCapacity); | |
496 parent_locales->push_back(parent); | |
497 UErrorCode err = U_ZERO_ERROR; | |
498 while (uloc_getParent(parent, parent, kNameCapacity, &err) > 0) { | |
499 if (U_FAILURE(err)) | |
500 break; | |
501 parent_locales->push_back(parent); | |
502 } | |
503 } | |
504 | |
505 bool IsValidLocaleSyntax(const std::string& locale) { | |
506 // This implements a simple approximation of BCP 47; it will accept all | |
507 // valid strings and reject some (but not all) invalid ones. | |
508 // http://www.unicode.org/reports/tr35/ | |
509 // #Unicode_Language_and_Locale_Identifiers | |
Nebojša Ćirić
2010/12/10 21:42:35
You could move some (url to TR35) to .h file and r
| |
510 | |
511 // Check that the length is plausible. | |
512 if (locale.size() < 2 || locale.size() >= ULOC_FULLNAME_CAPACITY) | |
513 return false; | |
514 | |
515 // Strip off the part after an '@' sign, which might contain keywords, | |
516 // as in en_IE@currency=IEP or fr@collation=phonebook;calendar=islamic-civil. | |
517 // We don't validate that part much, just check that there's at least one | |
518 // equals sign in a plausible place. | |
519 std::string prefix = locale; | |
520 if (locale.find("@") != std::string::npos) { | |
521 size_t split_point = locale.find("@"); | |
Nebojša Ćirić
2010/12/10 21:42:35
You could do:
size_t split_point = locale.find("@"
| |
522 std::string keywords = locale.substr(split_point + 1); | |
523 prefix = locale.substr(0, split_point); | |
524 | |
525 size_t equals_loc = keywords.find("="); | |
526 if (equals_loc == std::string::npos || | |
527 equals_loc < 1 || equals_loc > keywords.size() - 2) | |
528 return false; | |
529 } | |
530 | |
531 // Check that all characters before the at-sign are alphanumeric, hyphen, | |
532 // or underscore. | |
Nebojša Ćirić
2010/12/10 21:42:35
You could call NormalizeLocale before processing t
| |
533 for (size_t i = 0; i < prefix.size(); i++) { | |
534 char ch = prefix[i]; | |
535 if (!IsAsciiAlpha(ch) && !IsAsciiDigit(ch) && ch != '-' && ch != '_') | |
536 return false; | |
537 } | |
538 | |
539 // Check that the initial token (before the first hyphen/underscore) | |
540 // is 1 - 3 alphabetical characters (a language tag). | |
541 for (size_t i = 0; i < prefix.size(); i++) { | |
542 char ch = prefix[i]; | |
543 if (ch == '-' || ch == '_') { | |
544 if (i < 1 || i > 3) | |
545 return false; | |
546 break; | |
547 } | |
548 if (!IsAsciiAlpha(ch)) | |
549 return false; | |
550 } | |
551 | |
552 // Check that the all tokens after the initial token are 1 - 8 characters. | |
553 // (Tokenize/StringTokenizer don't work here, they collapse multiple | |
554 // delimiters into one.) | |
555 int token_len = 0; | |
556 int token_index = 0; | |
557 for (size_t i = 0; i < prefix.size(); i++) { | |
558 char ch = prefix[i]; | |
559 if (ch == '-' || ch == '_') { | |
560 if (token_index > 0 && (token_len < 1 || token_len > 8)) { | |
561 return false; | |
562 } | |
563 token_index++; | |
564 token_len = 0; | |
565 } else { | |
566 token_len++; | |
567 } | |
568 } | |
569 if (token_index == 0 && (token_len < 1 || token_len > 3)) { | |
570 return false; | |
571 } else if (token_len < 1 || token_len > 8) { | |
572 return false; | |
573 } | |
574 | |
575 return true; | |
576 } | |
577 | |
481 std::wstring GetString(int message_id) { | 578 std::wstring GetString(int message_id) { |
482 return UTF16ToWide(GetStringUTF16(message_id)); | 579 return UTF16ToWide(GetStringUTF16(message_id)); |
483 } | 580 } |
484 | 581 |
485 std::string GetStringUTF8(int message_id) { | 582 std::string GetStringUTF8(int message_id) { |
486 return UTF16ToUTF8(GetStringUTF16(message_id)); | 583 return UTF16ToUTF8(GetStringUTF16(message_id)); |
487 } | 584 } |
488 | 585 |
489 string16 GetStringUTF16(int message_id) { | 586 string16 GetStringUTF16(int message_id) { |
490 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 587 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 for (size_t i = 0; i < arraysize(kAcceptLanguageList); ++i) { | 969 for (size_t i = 0; i < arraysize(kAcceptLanguageList); ++i) { |
873 if (!IsLocaleNameTranslated(kAcceptLanguageList[i], display_locale)) | 970 if (!IsLocaleNameTranslated(kAcceptLanguageList[i], display_locale)) |
874 // TODO(jungshik) : Put them at the of the list with language codes | 971 // TODO(jungshik) : Put them at the of the list with language codes |
875 // enclosed by brackets instead of skipping. | 972 // enclosed by brackets instead of skipping. |
876 continue; | 973 continue; |
877 locale_codes->push_back(kAcceptLanguageList[i]); | 974 locale_codes->push_back(kAcceptLanguageList[i]); |
878 } | 975 } |
879 } | 976 } |
880 | 977 |
881 } // namespace l10n_util | 978 } // namespace l10n_util |
OLD | NEW |