unit_tests/ex_Lexicon.cc (81 lines of code) (raw):

// SPDX-License-Identifier: Apache-2.0 // Copyright Verizon Media 2020 /** @file Lexicon example code. */ #include <bitset> #include "swoc/Lexicon.h" #include "swoc/swoc_file.h" #include "swoc/swoc_ip.h" #include "catch.hpp" // Example code for documentatoin // --- // This is the set of address flags // doc.1.begin enum class NetType { EXTERNAL = 0, // 0x1 PROD, // 0x2 SECURE, // 0x4 EDGE, // 0x8 INVALID }; // doc.1.end // The number of distinct flags. static constexpr size_t N_TYPES = size_t(NetType::INVALID); // Set up a Lexicon to convert between the enumeration and strings. // doc.2.begin swoc::Lexicon<NetType> const NetTypeNames{ {{NetType::EXTERNAL, "external"}, {NetType::PROD, "prod"}, {NetType::SECURE, "secure"}, {NetType::EDGE, "edge"}}, NetType::INVALID // default value for undefined name }; // doc.2.end // A bit set for the flags. using Flags = std::bitset<N_TYPES>; TEST_CASE("Lexicon Example", "[libts][Lexicon]") { swoc::IPSpace<Flags> space; // Space in which to store the flags. // Load the file contents // doc.file.begin swoc::TextView text{R"( 10.0.0.2-10.0.0.254,edge 10.12.0.0/25,prod 10.15.37.10-10.15.37.99,prod,secure 172.19.0.0/22,external,secure 192.168.18.0/23,external,prod )"}; // doc.file.end // doc.load.begin // Process all the lines in the file. while (text) { auto line = text.take_prefix_at('\n').trim_if(&isspace); auto addr_token = line.take_prefix_at(','); // first token is the range. swoc::IPRange r{addr_token}; if (!r.empty()) { // empty means failed parse. Flags flags; while (line) { // parse out the rest of the comma separated elements auto token = line.take_prefix_at(','); auto idx = NetTypeNames[token]; if (idx != NetType::INVALID) { // one of the valid strings flags.set(static_cast<int>(idx)); // set the bit } } space.mark(r, flags); // store the flags in the spae. } } // doc.load.end using AddrCase = std::tuple<swoc::IPAddr, Flags>; using swoc::IPAddr; std::array<AddrCase, 5> AddrList = { {{IPAddr{"10.0.0.6"}, 0x8}, {IPAddr{"172.19.3.31"}, 0x5}, {IPAddr{"192.168.18.19"}, 0x3}, {IPAddr{"10.15.37.57"}, 0x6}, {IPAddr{"10.12.0.126"}, 0x2}} }; for (auto const &[addr, bits] : AddrList) { // doc.lookup.begin auto [range, flags] = *space.find(addr); // doc.lookup.end REQUIRE_FALSE(range.empty()); CHECK(flags == bits); } // doc.lookup.end } namespace { // doc.ctor.1.begin swoc::Lexicon<NetType> const Example1{ {{NetType::EXTERNAL, "external"}, {NetType::PROD, "prod"}, {NetType::SECURE, "secure"}, {NetType::EDGE, "edge"}}, "*invalid*", // default name for undefined values NetType::INVALID // default value for undefined name }; // doc.ctor.1.end // doc.ctor.2.begin swoc::Lexicon<NetType> const Example2{ {{NetType::EXTERNAL, "external"}, {NetType::PROD, "prod"}, {NetType::SECURE, "secure"}, {NetType::EDGE, "edge"}}, }; // doc.ctor.2.end // doc.ctor.3.begin swoc::Lexicon<NetType> Example3{ "*invalid*", // default name for undefined values NetType::INVALID // default value for undefined name }; // doc.ctor.3.end // doc.ctor.4.begin enum BoolTag { INVALID = -1, False = 0, True = 1, }; swoc::Lexicon<BoolTag> const BoolNames{ {{BoolTag::True, {"true", "1", "on", "enable", "Y", "yes"}}, {BoolTag::False, {"false", "0", "off", "disable", "N", "no"}}}, BoolTag::INVALID }; // doc.ctor.4.end } // namespace