Chromium Code Reviews| Index: third_party/libaddressinput/chromium/cpp/src/address_data.cc |
| diff --git a/third_party/libaddressinput/chromium/cpp/src/address_data.cc b/third_party/libaddressinput/chromium/cpp/src/address_data.cc |
| index 9b86cc8585f79e18577f814e6a1bd185710c3d2e..fbd1b799c2627c8cefe30985637518e8d1ff7baa 100644 |
| --- a/third_party/libaddressinput/chromium/cpp/src/address_data.cc |
| +++ b/third_party/libaddressinput/chromium/cpp/src/address_data.cc |
| @@ -11,17 +11,241 @@ |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| +// |
| +// The language-to-script and country-to-script mapping is loosely based on: |
| +// http://unicode.org/cldr/trac/browser/tags/release-24/common/supplemental/supplementalData.xml |
| #include <libaddressinput/address_data.h> |
| #include <libaddressinput/address_field.h> |
| +#include <algorithm> |
| #include <cassert> |
| +#include <cstddef> |
| +#include <ostream> |
| +#include <sstream> |
| #include <string> |
| +#include <vector> |
| + |
| +#include "region_data_constants.h" |
| +#include "rule.h" |
| namespace i18n { |
| namespace addressinput { |
| +namespace { |
| + |
| +enum Script { |
| + ARAB, |
| + HANG, |
| + HANS, |
| + HANT, |
| + JPAN, |
| + THAI, |
| + OTHER |
| +}; |
| + |
| +std::string GetAddressLanguageCode(const AddressData& address, |
| + const Rule& rule) { |
| + std::vector<std::string>::const_iterator it = |
| + std::find(rule.GetLanguages().begin(), |
| + rule.GetLanguages().end(), |
| + address.language_code); |
| + if (it != rule.GetLanguages().end()) { |
| + return *it; |
| + } else if (!rule.GetLanguage().empty()) { |
| + return rule.GetLanguage(); |
| + } else { |
| + return std::string(); |
| + } |
| +} |
| + |
| +Script GetCountryScript(const std::string& country_code) { |
| + if (country_code == "JP") { |
| + return JPAN; |
| + } else if (country_code == "HK" || |
| + country_code == "MO" || |
| + country_code == "TW") { |
| + return HANT; |
| + } else if (country_code == "CN") { |
| + return HANS; |
| + } else if (country_code == "AE" || |
| + country_code == "AF" || |
| + country_code == "BH" || |
| + country_code == "DZ" || |
| + country_code == "EG" || |
| + country_code == "EH" || |
| + country_code == "IQ" || |
| + country_code == "IR" || |
| + country_code == "JO" || |
| + country_code == "KM" || |
| + country_code == "KW" || |
| + country_code == "LB" || |
| + country_code == "LY" || |
| + country_code == "MA" || |
| + country_code == "MR" || |
| + country_code == "OM" || |
| + country_code == "PK" || |
| + country_code == "PS" || |
| + country_code == "QA" || |
| + country_code == "SA" || |
| + country_code == "SD" || |
| + country_code == "SY" || |
| + country_code == "TN" || |
| + country_code == "YE") { |
| + return ARAB; |
| + } else if (country_code == "KP" || |
| + country_code == "KR") { |
| + return HANG; |
| + } else if (country_code == "TH") { |
| + return THAI; |
| + } |
| + return OTHER; |
| +} |
| + |
| +Script GetLanguageScript(const std::string& language_code) { |
| + if (language_code == "ja") { |
| + return JPAN; |
| + } else if (language_code == "zh" || |
| + language_code == "zh-hant") { |
| + return HANT; |
| + } else if (language_code == "zh-hans") { |
| + return HANS; |
| + } else if (language_code == "ar" || |
| + language_code == "cjm" || |
| + language_code == "doi" || |
| + language_code == "fa" || |
| + language_code == "lah" || |
| + language_code == "prd" || |
| + language_code == "ps" || |
| + language_code == "swb" || |
| + language_code == "ug" || |
| + language_code == "ur") { |
| + return ARAB; |
| + } else if (language_code == "ko") { |
| + return HANG; |
| + } else if (language_code == "kdt" || |
| + language_code == "lcp" || |
| + language_code == "lwl" || |
| + language_code == "th" || |
| + language_code == "tts") { |
| + return THAI; |
| + } |
| + return OTHER; |
| +} |
| + |
| +std::string GetCompactLineSeparator(Script script) { |
| + switch (script) { |
| + case JPAN: |
| + case HANT: |
| + case HANS: |
| + return ""; |
| + case ARAB: |
| + return "، "; |
| + case HANG: |
| + case THAI: |
| + return " "; |
| + default: |
| + return ", "; |
| + } |
| +} |
| + |
| +std::string GetCompactLineSeparator(const AddressData& address, |
| + const Rule& rule) { |
| + std::string language_code = GetAddressLanguageCode(address, rule); |
| + return GetCompactLineSeparator( |
| + !language_code.empty() ? GetLanguageScript(language_code) |
| + : GetCountryScript(address.country_code)); |
| +} |
| + |
| +void BuildLines(const std::vector<std::vector<FormatElement> >& format, |
| + const AddressData& address, |
| + std::vector<std::string>* lines) { |
| + assert(lines != NULL); |
| + lines->clear(); |
| + |
| + for (size_t i = 0; i < format.size(); ++i) { |
| + if (format[i].empty()) { |
| + continue; |
| + } |
| + |
| + std::stringstream line; |
| + for (size_t j = 0; j < format[i].size(); ++j) { |
| + const FormatElement& element = format[i][j]; |
| + switch (element.type) { |
| + case FormatElement::LITERAL: |
| + line << element.literal; |
| + break; |
| + |
| + case FormatElement::FIELD: |
| + if (element.field == STREET_ADDRESS) { |
| + for (size_t k = 0; k < address.address_lines.size(); ++k) { |
| + if (address.address_lines.empty()) { |
| + continue; |
| + } |
| + // A street address is always surrounded by either newlines or |
| + // spaces. |
| + if (format[i].size() == 1) { |
| + lines->push_back(address.address_lines[k]); |
| + } else { |
| + line << address.address_lines[k]; |
| + if (k < address.address_lines.size() - 1) { |
| + line << " "; |
| + } |
| + } |
| + } |
| + } else { |
| + const std::string& field = address.GetField(element.field); |
| + if (!field.empty()) { |
| + line << field; |
| + } |
| + } |
| + break; |
| + |
| + default: |
| + assert(false); |
| + break; |
| + } |
| + } |
| + |
| + if (line.tellp() > 0) { |
| + lines->push_back(line.str()); |
| + } |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +std::string AddressData::ToString(FormatType format_type) const { |
| + Rule rule; |
| + rule.CopyFrom(Rule::GetDefault()); |
| + rule.ParseSerializedRule(RegionDataConstants::GetRegionData(country_code)); |
| + |
| + std::vector<std::string> lines; |
| + BuildLines(rule.GetFormat(), *this, &lines); |
| + |
| + std::string line_separator = "\n"; |
| + std::string mid_address_separator = "\n"; |
| + if (format_type != FORMAT_FULL) { |
| + line_separator = GetCompactLineSeparator(*this, rule); |
| + if (format_type == FORMAT_ONE_LINE) { |
| + mid_address_separator = line_separator; |
| + } |
| + } |
| + |
| + std::stringstream ss; |
|
Evan Stade
2014/01/13 22:04:39
nit: use std::string and concatenation
please use gerrit instead
2014/01/14 01:17:47
Done.
|
| + for (size_t i = 0; i < lines.size(); ++i) { |
| + ss << lines[i]; |
| + if (i + 1 == lines.size() / 2) { |
| + ss << mid_address_separator; |
| + } else if (i != lines.size() - 1) { |
| + ss << line_separator; |
| + } |
| + } |
| + |
| + return ss.str(); |
| +} |
| + |
| const std::string& AddressData::GetField(AddressField field) const { |
| switch (field) { |
| case COUNTRY: |