address.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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_DEPENDENT_LOCALITY: 53 return dependent_locality_; 54 55 case ADDRESS_HOME_CITY: 56 return city_; 57 58 case ADDRESS_HOME_STATE: 59 return state_; 60 61 case ADDRESS_HOME_ZIP: 62 return zip_code_; 63 64 case ADDRESS_HOME_SORTING_CODE: 65 return sorting_code_; 66 67 case ADDRESS_HOME_COUNTRY: 68 return base::ASCIIToUTF16(country_code_); 69 70 case ADDRESS_HOME_STREET_ADDRESS: 71 return JoinString(street_address_, '\n'); 72 73 default: 74 NOTREACHED(); 75 return base::string16(); 76 } 77} 78 79void Address::SetRawInfo(ServerFieldType type, const base::string16& value) { 80 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); 81 switch (type) { 82 case ADDRESS_HOME_LINE1: 83 if (street_address_.empty()) 84 street_address_.resize(1); 85 street_address_[0] = value; 86 TrimStreetAddress(); 87 break; 88 89 case ADDRESS_HOME_LINE2: 90 if (street_address_.size() < 2) 91 street_address_.resize(2); 92 street_address_[1] = value; 93 TrimStreetAddress(); 94 break; 95 96 case ADDRESS_HOME_DEPENDENT_LOCALITY: 97 dependent_locality_ = value; 98 break; 99 100 case ADDRESS_HOME_CITY: 101 city_ = value; 102 break; 103 104 case ADDRESS_HOME_STATE: 105 state_ = value; 106 break; 107 108 case ADDRESS_HOME_COUNTRY: 109 DCHECK(value.empty() || 110 (value.length() == 2u && IsStringASCII(value))); 111 country_code_ = UTF16ToASCII(value); 112 break; 113 114 case ADDRESS_HOME_ZIP: 115 zip_code_ = value; 116 break; 117 118 case ADDRESS_HOME_SORTING_CODE: 119 sorting_code_ = value; 120 break; 121 122 case ADDRESS_HOME_STREET_ADDRESS: 123 base::SplitString(value, base::char16('\n'), &street_address_); 124 break; 125 126 default: 127 NOTREACHED(); 128 } 129} 130 131base::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_); 135 136 ServerFieldType storable_type = type.GetStorableType(); 137 if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty()) 138 return AutofillCountry(country_code_, app_locale).name(); 139 140 return GetRawInfo(storable_type); 141} 142 143bool 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(); 149 return false; 150 } 151 152 country_code_ = StringToUpperASCII(UTF16ToASCII(value)); 153 return true; 154 } 155 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(); 160 } 161 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(); 169 return false; 170 } 171 172 SetRawInfo(storable_type, value); 173 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(); 181 return false; 182 } 183 184 return true; 185} 186 187void 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); 191 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); 196} 197 198void 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); 208} 209 210void Address::TrimStreetAddress() { 211 while (!street_address_.empty() && street_address_.back().empty()) { 212 street_address_.pop_back(); 213 } 214} 215 216} // namespace autofill 217