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 19namespace autofill { 20 21Address::Address() {} 22 23Address::Address(const Address& address) : FormGroup() { 24 *this = address; 25} 26 27Address::~Address() {} 28 29Address& 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 43base::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 82void 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 141base::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 153bool 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 // If the address doesn't have any newlines, don't attempt to parse it into 176 // lines, since this is potentially a user-entered address in the user's own 177 // format, so the code would have to rely on iffy heuristics at best. 178 // Instead, just give up when importing addresses like this. 179 if (storable_type == ADDRESS_HOME_STREET_ADDRESS && !value.empty() && 180 value.find(base::char16('\n')) == base::string16::npos) { 181 street_address_.clear(); 182 return false; 183 } 184 185 SetRawInfo(storable_type, value); 186 187 // Likewise, give up when importing addresses with any entirely blank lines. 188 // There's a good chance that this formatting is not intentional, but it's 189 // also not obviously safe to just strip the newlines. 190 if (storable_type == ADDRESS_HOME_STREET_ADDRESS && 191 std::find(street_address_.begin(), street_address_.end(), 192 base::string16()) != street_address_.end()) { 193 street_address_.clear(); 194 return false; 195 } 196 197 return true; 198} 199 200void Address::GetMatchingTypes(const base::string16& text, 201 const std::string& app_locale, 202 ServerFieldTypeSet* matching_types) const { 203 FormGroup::GetMatchingTypes(text, app_locale, matching_types); 204 205 // Check to see if the |text| canonicalized as a country name is a match. 206 std::string country_code = AutofillCountry::GetCountryCode(text, app_locale); 207 if (!country_code.empty() && country_code_ == country_code) 208 matching_types->insert(ADDRESS_HOME_COUNTRY); 209} 210 211void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { 212 supported_types->insert(ADDRESS_HOME_LINE1); 213 supported_types->insert(ADDRESS_HOME_LINE2); 214 supported_types->insert(ADDRESS_HOME_LINE3); 215 supported_types->insert(ADDRESS_HOME_STREET_ADDRESS); 216 supported_types->insert(ADDRESS_HOME_DEPENDENT_LOCALITY); 217 supported_types->insert(ADDRESS_HOME_CITY); 218 supported_types->insert(ADDRESS_HOME_STATE); 219 supported_types->insert(ADDRESS_HOME_ZIP); 220 supported_types->insert(ADDRESS_HOME_SORTING_CODE); 221 supported_types->insert(ADDRESS_HOME_COUNTRY); 222} 223 224void Address::TrimStreetAddress() { 225 while (!street_address_.empty() && street_address_.back().empty()) { 226 street_address_.pop_back(); 227 } 228} 229 230} // namespace autofill 231