OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/autofill/autofill_country.h" | 5 #include "chrome/browser/autofill/autofill_country.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 | 383 |
384 // Returns an ICU collator -- i.e. string comparator -- appropriate for the | 384 // Returns an ICU collator -- i.e. string comparator -- appropriate for the |
385 // given |locale|. | 385 // given |locale|. |
386 icu::Collator* GetCollatorForLocale(const std::string& locale); | 386 icu::Collator* GetCollatorForLocale(const std::string& locale); |
387 | 387 |
388 // Returns the ICU sort key corresponding to |str| for the given |collator|. | 388 // Returns the ICU sort key corresponding to |str| for the given |collator|. |
389 // Uses |buffer| as temporary storage, and might resize |buffer| as a side- | 389 // Uses |buffer| as temporary storage, and might resize |buffer| as a side- |
390 // effect. |buffer_size| should specify the |buffer|'s size, and is updated if | 390 // effect. |buffer_size| should specify the |buffer|'s size, and is updated if |
391 // the |buffer| is resized. | 391 // the |buffer| is resized. |
392 const std::string GetSortKey(const icu::Collator& collator, | 392 const std::string GetSortKey(const icu::Collator& collator, |
393 const string16& str, | 393 const icu::UnicodeString& str, |
394 scoped_array<uint8_t>* buffer, | 394 scoped_array<uint8_t>* buffer, |
395 int32_t* buffer_size) const; | 395 int32_t* buffer_size) const; |
396 | 396 |
397 | 397 |
398 // Maps from common country names, including 2- and 3-letter country codes, | 398 // Maps from common country names, including 2- and 3-letter country codes, |
399 // to the corresponding 2-letter country codes. The keys are uppercase ASCII | 399 // to the corresponding 2-letter country codes. The keys are uppercase ASCII |
400 // strings. | 400 // strings. |
401 std::map<std::string, std::string> common_names_; | 401 std::map<std::string, std::string> common_names_; |
402 | 402 |
403 // The outer map keys are ICU locale identifiers. | 403 // The outer map keys are ICU locale identifiers. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 return GetCountryCodeForLocalizedName(country, "en_US"); | 475 return GetCountryCodeForLocalizedName(country, "en_US"); |
476 } | 476 } |
477 | 477 |
478 void CountryNames::AddLocalizedNamesForLocale(const std::string& locale) { | 478 void CountryNames::AddLocalizedNamesForLocale(const std::string& locale) { |
479 // Nothing to do if we've previously added the localized names for the given | 479 // Nothing to do if we've previously added the localized names for the given |
480 // |locale|. | 480 // |locale|. |
481 if (locales_to_localized_names_.count(locale)) | 481 if (locales_to_localized_names_.count(locale)) |
482 return; | 482 return; |
483 | 483 |
484 std::map<std::string, std::string> localized_names; | 484 std::map<std::string, std::string> localized_names; |
| 485 |
| 486 icu::Locale icu_locale(locale.c_str()); |
485 const icu::Collator* collator = GetCollatorForLocale(locale); | 487 const icu::Collator* collator = GetCollatorForLocale(locale); |
| 488 |
486 int32_t buffer_size = 1000; | 489 int32_t buffer_size = 1000; |
487 scoped_array<uint8_t> buffer(new uint8_t[buffer_size]); | 490 scoped_array<uint8_t> buffer(new uint8_t[buffer_size]); |
488 | 491 |
489 for (CountryDataMap::Iterator it = CountryDataMap::Begin(); | 492 for (CountryDataMap::Iterator it = CountryDataMap::Begin(); |
490 it != CountryDataMap::End(); | 493 it != CountryDataMap::End(); |
491 ++it) { | 494 ++it) { |
492 const std::string& country_code = it->first; | 495 const std::string& country_code = it->first; |
493 string16 country_name = l10n_util::GetDisplayNameForCountry(country_code, | 496 |
494 locale); | 497 icu::Locale country_locale(NULL, country_code.c_str()); |
| 498 icu::UnicodeString country_name; |
| 499 country_locale.getDisplayName(icu_locale, country_name); |
495 std::string sort_key = GetSortKey(*collator, | 500 std::string sort_key = GetSortKey(*collator, |
496 country_name, | 501 country_name, |
497 &buffer, | 502 &buffer, |
498 &buffer_size); | 503 &buffer_size); |
499 | 504 |
500 localized_names.insert(std::make_pair(sort_key, country_code)); | 505 localized_names.insert(std::make_pair(sort_key, country_code)); |
501 } | 506 } |
502 | 507 |
503 locales_to_localized_names_.insert(std::make_pair(locale, localized_names)); | 508 locales_to_localized_names_.insert(std::make_pair(locale, localized_names)); |
504 } | 509 } |
505 | 510 |
506 const std::string CountryNames::GetCountryCodeForLocalizedName( | 511 const std::string CountryNames::GetCountryCodeForLocalizedName( |
507 const string16& country_name, | 512 const string16& country_name, |
508 const std::string& locale) { | 513 const std::string& locale) { |
509 AddLocalizedNamesForLocale(locale); | 514 AddLocalizedNamesForLocale(locale); |
510 | 515 |
511 icu::Collator* collator = GetCollatorForLocale(locale); | 516 icu::Collator* collator = GetCollatorForLocale(locale); |
512 | 517 |
513 // As recommended[1] by ICU, initialize the buffer size to four times the | 518 // As recommended[1] by ICU, initialize the buffer size to four times the |
514 // source string length. | 519 // source string length. |
515 // [1] http://userguide.icu-project.org/collation/api#TOC-Examples | 520 // [1] http://userguide.icu-project.org/collation/api#TOC-Examples |
516 int32_t buffer_size = country_name.size() * 4; | 521 int32_t buffer_size = country_name.size() * 4; |
517 scoped_array<uint8_t> buffer(new uint8_t[buffer_size]); | 522 scoped_array<uint8_t> buffer(new uint8_t[buffer_size]); |
518 std::string sort_key = GetSortKey(*collator, | 523 std::string sort_key = GetSortKey(*collator, |
519 country_name, | 524 country_name.c_str(), |
520 &buffer, | 525 &buffer, |
521 &buffer_size); | 526 &buffer_size); |
522 | 527 |
523 const std::map<std::string, std::string>& localized_names = | 528 const std::map<std::string, std::string>& localized_names = |
524 locales_to_localized_names_[locale]; | 529 locales_to_localized_names_[locale]; |
525 std::map<std::string, std::string>::const_iterator result = | 530 std::map<std::string, std::string>::const_iterator result = |
526 localized_names.find(sort_key); | 531 localized_names.find(sort_key); |
527 | 532 |
528 if (result != localized_names.end()) | 533 if (result != localized_names.end()) |
529 return result->second; | 534 return result->second; |
(...skipping 13 matching lines...) Expand all Loading... |
543 ignored = U_ZERO_ERROR; | 548 ignored = U_ZERO_ERROR; |
544 collator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, ignored); | 549 collator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, ignored); |
545 | 550 |
546 collators_.insert(std::make_pair(locale, collator)); | 551 collators_.insert(std::make_pair(locale, collator)); |
547 } | 552 } |
548 | 553 |
549 return collators_[locale]; | 554 return collators_[locale]; |
550 } | 555 } |
551 | 556 |
552 const std::string CountryNames::GetSortKey(const icu::Collator& collator, | 557 const std::string CountryNames::GetSortKey(const icu::Collator& collator, |
553 const string16& str, | 558 const icu::UnicodeString& str, |
554 scoped_array<uint8_t>* buffer, | 559 scoped_array<uint8_t>* buffer, |
555 int32_t* buffer_size) const { | 560 int32_t* buffer_size) const { |
556 DCHECK(buffer); | 561 DCHECK(buffer); |
557 DCHECK(buffer_size); | 562 DCHECK(buffer_size); |
558 | 563 |
559 icu::UnicodeString icu_str(str.c_str(), str.length()); | 564 int32_t expected_size = collator.getSortKey(str, buffer->get(), *buffer_size); |
560 int32_t expected_size = collator.getSortKey(icu_str, buffer->get(), | |
561 *buffer_size); | |
562 if (expected_size > *buffer_size) { | 565 if (expected_size > *buffer_size) { |
563 // If there wasn't enough space, grow the buffer and try again. | 566 // If there wasn't enough space, grow the buffer and try again. |
564 *buffer_size = expected_size; | 567 *buffer_size = expected_size; |
565 buffer->reset(new uint8_t[*buffer_size]); | 568 buffer->reset(new uint8_t[*buffer_size]); |
566 DCHECK(buffer->get()); | 569 DCHECK(buffer->get()); |
567 | 570 |
568 expected_size = collator.getSortKey(icu_str, buffer->get(), *buffer_size); | 571 expected_size = collator.getSortKey(str, buffer->get(), *buffer_size); |
569 DCHECK_EQ(*buffer_size, expected_size); | 572 DCHECK_EQ(*buffer_size, expected_size); |
570 } | 573 } |
571 | 574 |
572 return std::string(reinterpret_cast<const char*>(buffer->get())); | 575 return std::string(reinterpret_cast<const char*>(buffer->get())); |
573 } | 576 } |
574 | 577 |
| 578 // Returns the country name corresponding to |country_code|, localized to the |
| 579 // |display_locale|. |
| 580 string16 GetDisplayName(const std::string& country_code, |
| 581 const icu::Locale& display_locale) { |
| 582 icu::Locale country_locale(NULL, country_code.c_str()); |
| 583 icu::UnicodeString name; |
| 584 country_locale.getDisplayName(display_locale, name); |
| 585 |
| 586 DCHECK_GT(name.length(), 0); |
| 587 return string16(name.getBuffer(), name.length()); |
| 588 } |
| 589 |
575 } // namespace | 590 } // namespace |
576 | 591 |
577 AutofillCountry::AutofillCountry(const std::string& country_code, | 592 AutofillCountry::AutofillCountry(const std::string& country_code, |
578 const std::string& locale) { | 593 const std::string& locale) { |
579 const CountryDataMap::Iterator result = CountryDataMap::Find(country_code); | 594 const CountryDataMap::Iterator result = CountryDataMap::Find(country_code); |
580 DCHECK(result != CountryDataMap::End()); | 595 DCHECK(result != CountryDataMap::End()); |
581 const CountryData& data = result->second; | 596 const CountryData& data = result->second; |
582 | 597 |
583 country_code_ = country_code; | 598 country_code_ = country_code; |
584 name_ = l10n_util::GetDisplayNameForCountry(country_code, locale); | 599 name_ = GetDisplayName(country_code, icu::Locale(locale.c_str())); |
585 postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id); | 600 postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id); |
586 state_label_ = l10n_util::GetStringUTF16(data.state_label_id); | 601 state_label_ = l10n_util::GetStringUTF16(data.state_label_id); |
587 } | 602 } |
588 | 603 |
589 AutofillCountry::~AutofillCountry() { | 604 AutofillCountry::~AutofillCountry() { |
590 } | 605 } |
591 | 606 |
592 // static | 607 // static |
593 void AutofillCountry::GetAvailableCountries( | 608 void AutofillCountry::GetAvailableCountries( |
594 std::vector<std::string>* country_codes) { | 609 std::vector<std::string>* country_codes) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 | 651 |
637 AutofillCountry::AutofillCountry(const std::string& country_code, | 652 AutofillCountry::AutofillCountry(const std::string& country_code, |
638 const string16& name, | 653 const string16& name, |
639 const string16& postal_code_label, | 654 const string16& postal_code_label, |
640 const string16& state_label) | 655 const string16& state_label) |
641 : country_code_(country_code), | 656 : country_code_(country_code), |
642 name_(name), | 657 name_(name), |
643 postal_code_label_(postal_code_label), | 658 postal_code_label_(postal_code_label), |
644 state_label_(state_label) { | 659 state_label_(state_label) { |
645 } | 660 } |
OLD | NEW |