1 // Copyright (C) 2014 Google Inc.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include <libaddressinput/address_normalizer.h>
17 #include <libaddressinput/address_data.h>
18 #include <libaddressinput/address_field.h>
19 #include <libaddressinput/preload_supplier.h>
26 #include "lookup_key.h"
28 #include "util/string_compare.h"
31 namespace addressinput {
33 AddressNormalizer::AddressNormalizer(const PreloadSupplier* supplier)
34 : supplier_(supplier),
35 compare_(new StringCompare) {
36 assert(supplier_ != NULL);
39 AddressNormalizer::~AddressNormalizer() {}
41 void AddressNormalizer::Normalize(AddressData* address) const {
42 assert(address != NULL);
43 assert(supplier_->IsLoaded(address->region_code));
45 AddressData region_address;
46 region_address.region_code = address->region_code;
48 parent_key.FromAddress(region_address);
49 const Rule* parent_rule = supplier_->GetRule(parent_key);
50 assert(parent_rule != NULL);
53 for (size_t depth = 1; depth < arraysize(LookupKey::kHierarchy); ++depth) {
54 AddressField field = LookupKey::kHierarchy[depth];
55 if (address->IsFieldEmpty(field)) {
58 const std::string& field_value = address->GetFieldValue(field);
59 bool no_match_found_yet = true;
60 for (std::vector<std::string>::const_iterator
61 key_it = parent_rule->GetSubKeys().begin();
62 key_it != parent_rule->GetSubKeys().end(); ++key_it) {
63 lookup_key.FromLookupKey(parent_key, *key_it);
64 const Rule* rule = supplier_->GetRule(lookup_key);
67 bool matches_latin_name =
68 compare_->NaturalEquals(field_value, rule->GetLatinName());
69 bool matches_local_name_id =
70 compare_->NaturalEquals(field_value, *key_it) ||
71 compare_->NaturalEquals(field_value, rule->GetName());
72 if (matches_latin_name || matches_local_name_id) {
73 address->SetFieldValue(
74 field, matches_latin_name ? rule->GetLatinName() : *key_it);
75 no_match_found_yet = false;
76 parent_key.FromLookupKey(parent_key, *key_it);
77 parent_rule = supplier_->GetRule(parent_key);
78 assert(parent_rule != NULL);
82 if (no_match_found_yet) {
83 return; // Abort search.
88 } // namespace addressinput