1// Copyright (C) 2013 Google Inc.
2//
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
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
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.
14
15#include "address_field_util.h"
16
17#include <libaddressinput/address_field.h>
18
19#include <algorithm>
20#include <cassert>
21#include <cstddef>
22#include <map>
23#include <string>
24#include <utility>
25#include <vector>
26
27#include "format_element.h"
28
29namespace i18n {
30namespace addressinput {
31
32namespace {
33
34std::map<char, AddressField> InitFields() {
35  std::map<char, AddressField> fields;
36  fields.insert(std::make_pair('R', COUNTRY));
37  fields.insert(std::make_pair('S', ADMIN_AREA));
38  fields.insert(std::make_pair('C', LOCALITY));
39  fields.insert(std::make_pair('D', DEPENDENT_LOCALITY));
40  fields.insert(std::make_pair('X', SORTING_CODE));
41  fields.insert(std::make_pair('Z', POSTAL_CODE));
42  fields.insert(std::make_pair('A', STREET_ADDRESS));
43  fields.insert(std::make_pair('O', ORGANIZATION));
44  fields.insert(std::make_pair('N', RECIPIENT));
45  return fields;
46}
47
48const std::map<char, AddressField>& GetFields() {
49  static const std::map<char, AddressField> kFields(InitFields());
50  return kFields;
51}
52
53bool IsFieldToken(char c) {
54  return GetFields().find(c) != GetFields().end();
55}
56
57AddressField ParseFieldToken(char c) {
58  std::map<char, AddressField>::const_iterator it = GetFields().find(c);
59  assert(it != GetFields().end());
60  return it->second;
61}
62
63}  // namespace
64
65void ParseFormatRule(const std::string& format,
66                     std::vector<FormatElement>* elements) {
67  assert(elements != NULL);
68  elements->clear();
69
70  std::string::const_iterator prev = format.begin();
71  for (std::string::const_iterator next = format.begin();
72       next != format.end(); prev = ++next) {
73    // Find the next field element or newline (indicated by %<TOKEN>).
74    if ((next = std::find(next, format.end(), '%')) == format.end()) {
75      // No more tokens in the format string.
76      break;
77    }
78    if (prev < next) {
79      // Push back preceding literal.
80      elements->push_back(FormatElement(std::string(prev, next)));
81    }
82    if ((prev = ++next) == format.end()) {
83      // Move forward and check we haven't reached the end of the string
84      // (unlikely, it shouldn't end with %).
85      break;
86    }
87    // Process the token after the %.
88    if (*next == 'n') {
89      elements->push_back(FormatElement());
90    } else if (IsFieldToken(*next)) {
91      elements->push_back(FormatElement(ParseFieldToken(*next)));
92    }  // Else it's an unknown token, we ignore it.
93  }
94  // Push back any trailing literal.
95  if (prev != format.end()) {
96    elements->push_back(FormatElement(std::string(prev, format.end())));
97  }
98}
99
100void ParseAddressFieldsRequired(const std::string& required,
101                                std::vector<AddressField>* fields) {
102  assert(fields != NULL);
103  fields->clear();
104  for (std::string::const_iterator it = required.begin();
105       it != required.end(); ++it) {
106    if (IsFieldToken(*it)) {
107      fields->push_back(ParseFieldToken(*it));
108    }
109  }
110}
111
112}  // namespace addressinput
113}  // namespace i18n
114