Home | History | Annotate | Download | only in browser
      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