1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/autofill/core/browser/address.h"
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "components/autofill/core/browser/autofill_country.h"
16 #include "components/autofill/core/browser/autofill_field.h"
17 #include "components/autofill/core/browser/autofill_type.h"
23 Address::Address(const Address& address) : FormGroup() {
27 Address::~Address() {}
29 Address& Address::operator=(const Address& address) {
33 street_address_ = address.street_address_;
34 dependent_locality_ = address.dependent_locality_;
35 city_ = address.city_;
36 state_ = address.state_;
37 country_code_ = address.country_code_;
38 zip_code_ = address.zip_code_;
39 sorting_code_ = address.sorting_code_;
43 base::string16 Address::GetRawInfo(ServerFieldType type) const {
44 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group());
46 case ADDRESS_HOME_LINE1:
47 return street_address_.size() > 0 ? street_address_[0] : base::string16();
49 case ADDRESS_HOME_LINE2:
50 return street_address_.size() > 1 ? street_address_[1] : base::string16();
52 case ADDRESS_HOME_DEPENDENT_LOCALITY:
53 return dependent_locality_;
55 case ADDRESS_HOME_CITY:
58 case ADDRESS_HOME_STATE:
61 case ADDRESS_HOME_ZIP:
64 case ADDRESS_HOME_SORTING_CODE:
67 case ADDRESS_HOME_COUNTRY:
68 return base::ASCIIToUTF16(country_code_);
70 case ADDRESS_HOME_STREET_ADDRESS:
71 return JoinString(street_address_, '\n');
75 return base::string16();
79 void Address::SetRawInfo(ServerFieldType type, const base::string16& value) {
80 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group());
82 case ADDRESS_HOME_LINE1:
83 if (street_address_.empty())
84 street_address_.resize(1);
85 street_address_[0] = value;
89 case ADDRESS_HOME_LINE2:
90 if (street_address_.size() < 2)
91 street_address_.resize(2);
92 street_address_[1] = value;
96 case ADDRESS_HOME_DEPENDENT_LOCALITY:
97 dependent_locality_ = value;
100 case ADDRESS_HOME_CITY:
104 case ADDRESS_HOME_STATE:
108 case ADDRESS_HOME_COUNTRY:
109 DCHECK(value.empty() ||
110 (value.length() == 2u && IsStringASCII(value)));
111 country_code_ = base::UTF16ToASCII(value);
114 case ADDRESS_HOME_ZIP:
118 case ADDRESS_HOME_SORTING_CODE:
119 sorting_code_ = value;
122 case ADDRESS_HOME_STREET_ADDRESS:
123 base::SplitString(value, base::char16('\n'), &street_address_);
131 base::string16 Address::GetInfo(const AutofillType& type,
132 const std::string& app_locale) const {
133 if (type.html_type() == HTML_TYPE_COUNTRY_CODE)
134 return base::ASCIIToUTF16(country_code_);
136 ServerFieldType storable_type = type.GetStorableType();
137 if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty())
138 return AutofillCountry(country_code_, app_locale).name();
140 return GetRawInfo(storable_type);
143 bool Address::SetInfo(const AutofillType& type,
144 const base::string16& value,
145 const std::string& app_locale) {
146 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) {
147 if (!value.empty() && (value.size() != 2u || !IsStringASCII(value))) {
148 country_code_ = std::string();
152 country_code_ = StringToUpperASCII(base::UTF16ToASCII(value));
156 ServerFieldType storable_type = type.GetStorableType();
157 if (storable_type == ADDRESS_HOME_COUNTRY && !value.empty()) {
158 country_code_ = AutofillCountry::GetCountryCode(value, app_locale);
159 return !country_code_.empty();
162 // If the address doesn't have any newlines, don't attempt to parse it into
163 // lines, since this is potentially a user-entered address in the user's own
164 // format, so the code would have to rely on iffy heuristics at best.
165 // Instead, just give up when importing addresses like this.
166 if (storable_type == ADDRESS_HOME_STREET_ADDRESS && !value.empty() &&
167 value.find(base::char16('\n')) == base::string16::npos) {
168 street_address_.clear();
172 SetRawInfo(storable_type, value);
174 // Likewise, give up when importing addresses with any entirely blank lines.
175 // There's a good chance that this formatting is not intentional, but it's
176 // also not obviously safe to just strip the newlines.
177 if (storable_type == ADDRESS_HOME_STREET_ADDRESS &&
178 std::find(street_address_.begin(), street_address_.end(),
179 base::string16()) != street_address_.end()) {
180 street_address_.clear();
187 void Address::GetMatchingTypes(const base::string16& text,
188 const std::string& app_locale,
189 ServerFieldTypeSet* matching_types) const {
190 FormGroup::GetMatchingTypes(text, app_locale, matching_types);
192 // Check to see if the |text| canonicalized as a country name is a match.
193 std::string country_code = AutofillCountry::GetCountryCode(text, app_locale);
194 if (!country_code.empty() && country_code_ == country_code)
195 matching_types->insert(ADDRESS_HOME_COUNTRY);
198 void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
199 supported_types->insert(ADDRESS_HOME_LINE1);
200 supported_types->insert(ADDRESS_HOME_LINE2);
201 supported_types->insert(ADDRESS_HOME_STREET_ADDRESS);
202 supported_types->insert(ADDRESS_HOME_DEPENDENT_LOCALITY);
203 supported_types->insert(ADDRESS_HOME_CITY);
204 supported_types->insert(ADDRESS_HOME_STATE);
205 supported_types->insert(ADDRESS_HOME_ZIP);
206 supported_types->insert(ADDRESS_HOME_SORTING_CODE);
207 supported_types->insert(ADDRESS_HOME_COUNTRY);
210 void Address::TrimStreetAddress() {
211 while (!street_address_.empty() && street_address_.back().empty()) {
212 street_address_.pop_back();
216 } // namespace autofill