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