blob: 25c319f2a6b9e09cbea4e117a31c5e3b203ac920 [file] [log] [blame]
// 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
static_cast<void>(range);
REQUIRE(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