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 29 namespace i18n { 30 namespace addressinput { 31 32 namespace { 33 34 std::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 48 const std::map<char, AddressField>& GetFields() { 49 static const std::map<char, AddressField> kFields(InitFields()); 50 return kFields; 51 } 52 53 bool IsFieldToken(char c) { 54 return GetFields().find(c) != GetFields().end(); 55 } 56 57 AddressField 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 65 void 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 100 void 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