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. 4 5 #include "components/autofill/core/browser/address.h" 6 7 #include <stddef.h> 8 #include <algorithm> 9 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" 18 19 namespace autofill { 20 21 Address::Address() {} 22 23 Address::Address(const Address& address) : FormGroup() { 24 *this = address; 25 } 26 27 Address::~Address() {} 28 29 Address& Address::operator=(const Address& address) { 30 if (this == &address) 31 return *this; 32 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_; 40 return *this; 41 } 42 43 base::string16 Address::GetRawInfo(ServerFieldType type) const { 44 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); 45 switch (type) { 46 case ADDRESS_HOME_LINE1: 47 return street_address_.size() > 0 ? street_address_[0] : base::string16(); 48 49 case ADDRESS_HOME_LINE2: 50 return street_address_.size() > 1 ? street_address_[1] : base::string16(); 51 52 case ADDRESS_HOME_LINE3: 53 return street_address_.size() > 2 ? street_address_[2] : base::string16(); 54 55 case ADDRESS_HOME_DEPENDENT_LOCALITY: 56 return dependent_locality_; 57 58 case ADDRESS_HOME_CITY: 59 return city_; 60 61 case ADDRESS_HOME_STATE: 62 return state_; 63 64 case ADDRESS_HOME_ZIP: 65 return zip_code_; 66 67 case ADDRESS_HOME_SORTING_CODE: 68 return sorting_code_; 69 70 case ADDRESS_HOME_COUNTRY: 71 return base::ASCIIToUTF16(country_code_); 72 73 case ADDRESS_HOME_STREET_ADDRESS: 74 return JoinString(street_address_, '\n'); 75 76 default: 77 NOTREACHED(); 78 return base::string16(); 79 } 80 } 81 82 void Address::SetRawInfo(ServerFieldType type, const base::string16& value) { 83 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); 84 switch (type) { 85 case ADDRESS_HOME_LINE1: 86 if (street_address_.empty()) 87 street_address_.resize(1); 88 street_address_[0] = value; 89 TrimStreetAddress(); 90 break; 91 92 case ADDRESS_HOME_LINE2: 93 if (street_address_.size() < 2) 94 street_address_.resize(2); 95 street_address_[1] = value; 96 TrimStreetAddress(); 97 break; 98 99 case ADDRESS_HOME_LINE3: 100 if (street_address_.size() < 3) 101 street_address_.resize(3); 102 street_address_[2] = value; 103 TrimStreetAddress(); 104 break; 105 106 case ADDRESS_HOME_DEPENDENT_LOCALITY: 107 dependent_locality_ = value; 108 break; 109 110 case ADDRESS_HOME_CITY: 111 city_ = value; 112 break; 113 114 case ADDRESS_HOME_STATE: 115 state_ = value; 116 break; 117 118 case ADDRESS_HOME_COUNTRY: 119 DCHECK(value.empty() || 120 (value.length() == 2u && base::IsStringASCII(value))); 121 country_code_ = base::UTF16ToASCII(value); 122 break; 123 124 case ADDRESS_HOME_ZIP: 125 zip_code_ = value; 126 break; 127 128 case ADDRESS_HOME_SORTING_CODE: 129 sorting_code_ = value; 130 break; 131 132 case ADDRESS_HOME_STREET_ADDRESS: 133 base::SplitString(value, base::char16('\n'), &street_address_); 134 break; 135 136 default: 137 NOTREACHED(); 138 } 139 } 140 141 base::string16 Address::GetInfo(const AutofillType& type, 142 const std::string& app_locale) const { 143 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) 144 return base::ASCIIToUTF16(country_code_); 145 146 ServerFieldType storable_type = type.GetStorableType(); 147 if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty()) 148 return AutofillCountry(country_code_, app_locale).name(); 149 150 return GetRawInfo(storable_type); 151 } 152 153 bool Address::SetInfo(const AutofillType& type, 154 const base::string16& value, 155 const std::string& app_locale) { 156 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) { 157 if (!value.empty() && (value.size() != 2u || !base::IsStringASCII(value))) { 158 country_code_ = std::string(); 159 return false; 160 } 161 162 country_code_ = StringToUpperASCII(base::UTF16ToASCII(value)); 163 return true; 164 } else if (type.html_type() == HTML_TYPE_FULL_ADDRESS) { 165 // Parsing a full address is too hard. 166 return false; 167 } 168 169 ServerFieldType storable_type = type.GetStorableType(); 170 if (storable_type == ADDRESS_HOME_COUNTRY && !value.empty()) { 171 country_code_ = AutofillCountry::GetCountryCode(value, app_locale); 172 return !country_code_.empty(); 173 } 174 175 SetRawInfo(storable_type, value); 176 177 // Give up when importing addresses with any entirely blank lines. 178 // There's a good chance that this formatting is not intentional, but it's 179 // also not obviously safe to just strip the newlines. 180 if (storable_type == ADDRESS_HOME_STREET_ADDRESS && 181 std::find(street_address_.begin(), street_address_.end(), 182 base::string16()) != street_address_.end()) { 183 street_address_.clear(); 184 return false; 185 } 186 187 return true; 188 } 189 190 void Address::GetMatchingTypes(const base::string16& text, 191 const std::string& app_locale, 192 ServerFieldTypeSet* matching_types) const { 193 FormGroup::GetMatchingTypes(text, app_locale, matching_types); 194 195 // Check to see if the |text| canonicalized as a country name is a match. 196 std::string country_code = AutofillCountry::GetCountryCode(text, app_locale); 197 if (!country_code.empty() && country_code_ == country_code) 198 matching_types->insert(ADDRESS_HOME_COUNTRY); 199 } 200 201 void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { 202 supported_types->insert(ADDRESS_HOME_LINE1); 203 supported_types->insert(ADDRESS_HOME_LINE2); 204 supported_types->insert(ADDRESS_HOME_LINE3); 205 supported_types->insert(ADDRESS_HOME_STREET_ADDRESS); 206 supported_types->insert(ADDRESS_HOME_DEPENDENT_LOCALITY); 207 supported_types->insert(ADDRESS_HOME_CITY); 208 supported_types->insert(ADDRESS_HOME_STATE); 209 supported_types->insert(ADDRESS_HOME_ZIP); 210 supported_types->insert(ADDRESS_HOME_SORTING_CODE); 211 supported_types->insert(ADDRESS_HOME_COUNTRY); 212 } 213 214 void Address::TrimStreetAddress() { 215 while (!street_address_.empty() && street_address_.back().empty()) { 216 street_address_.pop_back(); 217 } 218 } 219 220 } // namespace autofill 221