File indexing completed on 2024-10-06 03:38:09
0001 /* 0002 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "addressformat_p.h" 0007 #include "addressformatparser_p.h" 0008 0009 #include <QDebug> 0010 0011 using namespace KContacts; 0012 0013 struct { 0014 char c; 0015 AddressFormatField f; 0016 } static constexpr const field_map[] = { 0017 {'A', AddressFormatField::StreetAddress}, 0018 {'C', AddressFormatField::Locality}, 0019 {'D', AddressFormatField::DependentLocality}, 0020 {'N', AddressFormatField::Name}, 0021 {'O', AddressFormatField::Organization}, 0022 {'P', AddressFormatField::PostOfficeBox}, 0023 {'R', AddressFormatField::Country}, 0024 {'S', AddressFormatField::Region}, 0025 {'X', AddressFormatField::SortingCode}, 0026 {'Z', AddressFormatField::PostalCode}, 0027 }; 0028 0029 AddressFormatField AddressFormatParser::parseField(QChar c) 0030 { 0031 const auto it = std::lower_bound(std::begin(field_map), std::end(field_map), c.cell(), [](auto lhs, auto rhs) { 0032 return lhs.c < rhs; 0033 }); 0034 if (it == std::end(field_map) || (*it).c != c.cell() || c.row() != 0) { 0035 return AddressFormatField::NoField; 0036 } 0037 return (*it).f; 0038 } 0039 0040 AddressFormatFields AddressFormatParser::parseFields(QStringView s) 0041 { 0042 AddressFormatFields fields; 0043 for (auto c : s) { 0044 fields |= parseField(c); 0045 } 0046 return fields; 0047 } 0048 0049 std::vector<AddressFormatElement> AddressFormatParser::parseElements(QStringView s) 0050 { 0051 std::vector<AddressFormatElement> elements; 0052 QString literal; 0053 for (auto it = s.begin(); it != s.end(); ++it) { 0054 if ((*it) == QLatin1Char('%') && std::next(it) != s.end()) { 0055 if (!literal.isEmpty()) { 0056 AddressFormatElement elem; 0057 auto e = AddressFormatElementPrivate::get(elem); 0058 e->literal = std::move(literal); 0059 elements.push_back(elem); 0060 } 0061 ++it; 0062 if ((*it) == QLatin1Char('n')) { 0063 elements.push_back(AddressFormatElement{}); 0064 } else { 0065 const auto f = parseField(*it); 0066 if (f == AddressFormatField::NoField) { 0067 qWarning() << "invalid format field element: %" << *it << "in" << s; 0068 } else { 0069 AddressFormatElement elem; 0070 auto e = AddressFormatElementPrivate::get(elem); 0071 e->field = f; 0072 elements.push_back(elem); 0073 } 0074 } 0075 } else { 0076 literal.push_back(*it); 0077 } 0078 } 0079 if (!literal.isEmpty()) { 0080 AddressFormatElement elem; 0081 auto e = AddressFormatElementPrivate::get(elem); 0082 e->literal = std::move(literal); 0083 elements.push_back(elem); 0084 } 0085 return elements; 0086 }