address.cc revision f2477e01787aa58f445919b809d89e252beef54f
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 9#include "base/basictypes.h" 10#include "base/logging.h" 11#include "base/strings/string_split.h" 12#include "base/strings/string_util.h" 13#include "base/strings/utf_string_conversions.h" 14#include "components/autofill/core/browser/autofill_country.h" 15#include "components/autofill/core/browser/autofill_field.h" 16#include "components/autofill/core/browser/autofill_type.h" 17 18namespace autofill { 19 20Address::Address() {} 21 22Address::Address(const Address& address) : FormGroup() { 23 *this = address; 24} 25 26Address::~Address() {} 27 28Address& Address::operator=(const Address& address) { 29 if (this == &address) 30 return *this; 31 32 line1_ = address.line1_; 33 line2_ = address.line2_; 34 city_ = address.city_; 35 state_ = address.state_; 36 country_code_ = address.country_code_; 37 zip_code_ = address.zip_code_; 38 return *this; 39} 40 41base::string16 Address::GetRawInfo(ServerFieldType type) const { 42 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); 43 switch (type) { 44 case ADDRESS_HOME_LINE1: 45 return line1_; 46 47 case ADDRESS_HOME_LINE2: 48 return line2_; 49 50 case ADDRESS_HOME_CITY: 51 return city_; 52 53 case ADDRESS_HOME_STATE: 54 return state_; 55 56 case ADDRESS_HOME_ZIP: 57 return zip_code_; 58 59 case ADDRESS_HOME_COUNTRY: 60 return ASCIIToUTF16(country_code_); 61 62 case ADDRESS_HOME_STREET_ADDRESS: { 63 base::string16 address = line1_; 64 if (!line2_.empty()) 65 address += ASCIIToUTF16("\n") + line2_; 66 return address; 67 } 68 69 // TODO(isherman): Add support for these field types in support of i18n. 70 case ADDRESS_HOME_SORTING_CODE: 71 case ADDRESS_HOME_DEPENDENT_LOCALITY: 72 return base::string16(); 73 74 default: 75 NOTREACHED(); 76 return base::string16(); 77 } 78} 79 80void Address::SetRawInfo(ServerFieldType type, const base::string16& value) { 81 DCHECK_EQ(ADDRESS_HOME, AutofillType(type).group()); 82 switch (type) { 83 case ADDRESS_HOME_LINE1: 84 line1_ = value; 85 break; 86 87 case ADDRESS_HOME_LINE2: 88 line2_ = value; 89 break; 90 91 case ADDRESS_HOME_CITY: 92 city_ = value; 93 break; 94 95 case ADDRESS_HOME_STATE: 96 state_ = value; 97 break; 98 99 case ADDRESS_HOME_COUNTRY: 100 DCHECK(value.empty() || 101 (value.length() == 2u && IsStringASCII(value))); 102 country_code_ = UTF16ToASCII(value); 103 break; 104 105 case ADDRESS_HOME_ZIP: 106 zip_code_ = value; 107 break; 108 109 case ADDRESS_HOME_STREET_ADDRESS: { 110 // Clear any stale values, which might or might not get overwritten below. 111 line1_.clear(); 112 line2_.clear(); 113 114 std::vector<base::string16> lines; 115 base::SplitString(value, char16('\n'), &lines); 116 if (lines.size() > 0) 117 line1_ = lines[0]; 118 if (lines.size() > 1) 119 line2_ = lines[1]; 120 121 // TODO(isherman): Add support for additional address lines. 122 break; 123 } 124 125 // TODO(isherman): Add support for these field types in support of i18n. 126 case ADDRESS_HOME_SORTING_CODE: 127 case ADDRESS_HOME_DEPENDENT_LOCALITY: 128 break; 129 130 default: 131 NOTREACHED(); 132 } 133} 134 135base::string16 Address::GetInfo(const AutofillType& type, 136 const std::string& app_locale) const { 137 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) 138 return ASCIIToUTF16(country_code_); 139 140 ServerFieldType storable_type = type.GetStorableType(); 141 if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty()) 142 return AutofillCountry(country_code_, app_locale).name(); 143 144 return GetRawInfo(storable_type); 145} 146 147bool Address::SetInfo(const AutofillType& type, 148 const base::string16& value, 149 const std::string& app_locale) { 150 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) { 151 if (!value.empty() && (value.size() != 2u || !IsStringASCII(value))) { 152 country_code_ = std::string(); 153 return false; 154 } 155 156 country_code_ = StringToUpperASCII(UTF16ToASCII(value)); 157 return true; 158 } 159 160 ServerFieldType storable_type = type.GetStorableType(); 161 if (storable_type == ADDRESS_HOME_COUNTRY && !value.empty()) { 162 country_code_ = AutofillCountry::GetCountryCode(value, app_locale); 163 return !country_code_.empty(); 164 } 165 166 // If the address doesn't have any newlines, don't attempt to parse it into 167 // lines, since this is potentially a user-entered address in the user's own 168 // format, so the code would have to rely on iffy heuristics at best. 169 // Instead, just give up when importing addresses like this. 170 if (storable_type == ADDRESS_HOME_STREET_ADDRESS && !value.empty() && 171 value.find(char16('\n')) == base::string16::npos) { 172 line1_ = line2_ = base::string16(); 173 return false; 174 } 175 176 SetRawInfo(storable_type, value); 177 return true; 178} 179 180void Address::GetMatchingTypes(const base::string16& text, 181 const std::string& app_locale, 182 ServerFieldTypeSet* matching_types) const { 183 FormGroup::GetMatchingTypes(text, app_locale, matching_types); 184 185 // Check to see if the |text| canonicalized as a country name is a match. 186 std::string country_code = AutofillCountry::GetCountryCode(text, app_locale); 187 if (!country_code.empty() && country_code_ == country_code) 188 matching_types->insert(ADDRESS_HOME_COUNTRY); 189} 190 191void Address::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { 192 supported_types->insert(ADDRESS_HOME_LINE1); 193 supported_types->insert(ADDRESS_HOME_LINE2); 194 supported_types->insert(ADDRESS_HOME_CITY); 195 supported_types->insert(ADDRESS_HOME_STATE); 196 supported_types->insert(ADDRESS_HOME_ZIP); 197 supported_types->insert(ADDRESS_HOME_COUNTRY); 198} 199 200} // namespace autofill 201