// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/autofill/core/browser/address.h" #include <stddef.h> #include <algorithm> #include "base/logging.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/country_names.h" #include "components/autofill/core/browser/state_names.h" #include "components/autofill/core/common/autofill_l10n_util.h" namespace autofill { Address::Address() {} Address::Address(const Address& address) : FormGroup() { *this = address; } Address::~Address() {} Address& Address::operator=(const Address& address) { if (this == &address) return *this; street_address_ = address.street_address_; dependent_locality_ = address.dependent_locality_; city_ = address.city_; state_ = address.state_; country_code_ = address.country_code_; zip_code_ = address.zip_code_; sorting_code_ = address.sorting_code_; return *this; } base::string16 Address::GetRawInfo(ServerFieldType type) const { DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); switch (type) { case ADDRESS_HOME_LINE1: return street_address_.size() > 0 ? street_address_[0] : base::string16(); case ADDRESS_HOME_LINE2: return street_address_.size() > 1 ? street_address_[1] : base::string16(); case ADDRESS_HOME_LINE3: return street_address_.size() > 2 ? street_address_[2] : base::string16(); case ADDRESS_HOME_DEPENDENT_LOCALITY: return dependent_locality_; case ADDRESS_HOME_CITY: return city_; case ADDRESS_HOME_STATE: return state_; case ADDRESS_HOME_ZIP: return zip_code_; case ADDRESS_HOME_SORTING_CODE: return sorting_code_; case ADDRESS_HOME_COUNTRY: return base::ASCIIToUTF16(country_code_); case ADDRESS_HOME_STREET_ADDRESS: return base::JoinString(street_address_, base::ASCIIToUTF16("\n")); default: NOTREACHED(); return base::string16(); } } void Address::SetRawInfo(ServerFieldType type, const base::string16& value) { DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); switch (type) { case ADDRESS_HOME_LINE1: if (street_address_.empty()) street_address_.resize(1); street_address_[0] = value; TrimStreetAddress(); break; case ADDRESS_HOME_LINE2: if (street_address_.size() < 2) street_address_.resize(2); street_address_[1] = value; TrimStreetAddress(); break; case ADDRESS_HOME_LINE3: if (street_address_.size() < 3) street_address_.resize(3); street_address_[2] = value; TrimStreetAddress(); break; case ADDRESS_HOME_DEPENDENT_LOCALITY: dependent_locality_ = value; break; case ADDRESS_HOME_CITY: city_ = value; break; case ADDRESS_HOME_STATE: state_ = value; break; case ADDRESS_HOME_COUNTRY: DCHECK(value.empty() || (value.length() == 2u && base::IsStringASCII(value))); country_code_ = base::UTF16ToASCII(value); break; case ADDRESS_HOME_ZIP: zip_code_ = value; break; case ADDRESS_HOME_SORTING_CODE: sorting_code_ = value; break; case ADDRESS_HOME_STREET_ADDRESS: street_address_ = base::SplitString( value, base::ASCIIToUTF16("\n"), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); break; default: NOTREACHED(); } } base::string16 Address::GetInfo(const AutofillType& type, const std::string& app_locale) const { if (type.html_type() == HTML_TYPE_COUNTRY_CODE) return base::ASCIIToUTF16(country_code_); ServerFieldType storable_type = type.GetStorableType(); if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty()) return AutofillCountry(country_code_, app_locale).name(); return GetRawInfo(storable_type); } bool Address::SetInfo(const AutofillType& type, const base::string16& value, const std::string& app_locale) { if (type.html_type() == HTML_TYPE_COUNTRY_CODE) { if (!value.empty() && (value.size() != 2u || !base::IsStringASCII(value))) { country_code_ = std::string(); return false; } country_code_ = base::ToUpperASCII(base::UTF16ToASCII(value)); return true; } else if (type.html_type() == HTML_TYPE_FULL_ADDRESS) { // Parsing a full address is too hard. return false; } ServerFieldType storable_type = type.GetStorableType(); if (storable_type == ADDRESS_HOME_COUNTRY && !value.empty()) { country_code_ = CountryNames::GetInstance()->GetCountryCode(value); return !country_code_.empty(); } SetRawInfo(storable_type, value); // Give up when importing addresses with any entirely blank lines. // There's a good chance that this formatting is not intentional, but it's // also not obviously safe to just strip the newlines. if (storable_type == ADDRESS_HOME_STREET_ADDRESS && std::find(street_address_.begin(), street_address_.end(), base::string16()) != street_address_.end()) { street_address_.clear(); return false; } return true; } void Address::GetMatchingTypes(const base::string16& text, const std::string& app_locale, ServerFieldTypeSet* matching_types) const { FormGroup::GetMatchingTypes(text, app_locale, matching_types); // Check to see if the |text| canonicalized as a country name is a match. std::string country_code = CountryNames::GetInstance()->GetCountryCode(text); if (!country_code.empty() && country_code_ == country_code) matching_types->insert(ADDRESS_HOME_COUNTRY); // Check to see if the |text| could be the full name or abbreviation of a // state. base::string16 canon_text = AutofillProfile::CanonicalizeProfileString(text); base::string16 state_name; base::string16 state_abbreviation; state_names::GetNameAndAbbreviation(canon_text, &state_name, &state_abbreviation); if (!state_name.empty() || !state_abbreviation.empty()) { l10n::CaseInsensitiveCompare compare; base::string16 canon_profile_state = AutofillProfile::CanonicalizeProfileString( GetInfo(AutofillType(ADDRESS_HOME_STATE), app_locale)); if ((!state_name.empty() && compare.StringsEqual(state_name, canon_profile_state)) || (!state_abbreviation.empty() && compare.StringsEqual(state_abbreviation, canon_profile_state))) { matching_types->insert(ADDRESS_HOME_STATE); } } } void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { supported_types->insert(ADDRESS_HOME_LINE1); supported_types->insert(ADDRESS_HOME_LINE2); supported_types->insert(ADDRESS_HOME_LINE3); supported_types->insert(ADDRESS_HOME_STREET_ADDRESS); supported_types->insert(ADDRESS_HOME_DEPENDENT_LOCALITY); supported_types->insert(ADDRESS_HOME_CITY); supported_types->insert(ADDRESS_HOME_STATE); supported_types->insert(ADDRESS_HOME_ZIP); supported_types->insert(ADDRESS_HOME_SORTING_CODE); supported_types->insert(ADDRESS_HOME_COUNTRY); } void Address::TrimStreetAddress() { while (!street_address_.empty() && street_address_.back().empty()) { street_address_.pop_back(); } } } // namespace autofill