Skip to content

Commit

Permalink
Add ex_netcompat.cc example.
Browse files Browse the repository at this point in the history
  • Loading branch information
SolidWallOfCode committed Apr 22, 2020
1 parent 2768927 commit 40203b0
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 6 deletions.
13 changes: 7 additions & 6 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ cmake_minimum_required(VERSION 3.12)
project(libswoc_examples CXX)
set(CMAKE_CXX_STANDARD 17)

add_executable(ex_netdb
ex_netdb.cc
)

target_link_libraries(ex_netdb PUBLIC swoc++)
add_executable(ex_netdb ex_netdb.cc)
target_link_libraries(ex_netdb PUBLIC libswoc)
set_target_properties(ex_netdb PROPERTIES CLANG_FORMAT_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_options(ex_netdb PRIVATE -Wall -Wextra -Werror -Wno-unused-parameter -Wno-format-truncation -Wno-stringop-overflow -Wno-invalid-offsetof)
target_compile_options(ex_netdb PRIVATE -Wall -Wextra -Werror)

add_executable(ex_netcompact ex_netcompact.cc)
target_link_libraries(ex_netcompact PUBLIC libswoc)
target_compile_options(ex_netcompact PRIVATE -Wall -Wextra -Werror)
102 changes: 102 additions & 0 deletions example/ex_netcompact.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2014 Network Geographics

/** @file
Example tool to compact networks.
Input is a file with addresses. Each line should be an address, an address range,
or a network in CIDR format.
4441:34F8:1E40:1EF:0:0:A0:0/108
192.168.12.1
10.0.23.0/23
The output is the same set of addresses in as few networks as possible.
*/

#include <unordered_set>
#include <fstream>

#include "swoc/TextView.h"
#include "swoc/swoc_ip.h"
#include "swoc/bwf_ip.h"
#include "swoc/bwf_std.h"
#include "swoc/bwf_std.h"
#include "swoc/swoc_file.h"

using namespace std::literals;
using namespace swoc::literals;

using swoc::TextView;

using swoc::IPAddr;
using swoc::IPRange;

/// Type for temporary buffer writer output.
using W = swoc::LocalBufferWriter<512>;

/// IPSpace for mapping address to @c Payload
using Space = swoc::IPSpace<std::monostate>;

/// Process the @a content of a file in to @a space.
unsigned process(Space& space, TextView content) {
int line_no = 0; /// Track for error reporting.
unsigned n_ranges = 0;

// For each line in @a content
for (TextView line ; ! (line = content.take_prefix_at('\n')).empty() ; ) {
++line_no;
line.trim_if(&isspace);
// Allow empty lines and '#' comments without error.
if (line.empty() || '#' == *line) {
continue;
}

// Get the range, make sure it's a valid range.
IPRange range{line};
if (range.empty()) {
std::cerr << W().print("Invalid range '{}' on line {}\n", line, line_no);
continue;
}
++n_ranges;
space.mark(range, std::monostate{});
}
return n_ranges;
}

int main(int argc, char *argv[]) {
Space space;

if (argc < 2) {
std::cerr << W().print("Input file name required.");
exit(1);
}

auto t0 = std::chrono::system_clock::now();
swoc::file::path path{argv[1]};
std::error_code ec;
std::string content = swoc::file::load(path, ec);
if (ec) {
std::cerr << W().print(R"(Failed to open file "{}" - {}\n)", path, ec);
exit(1);
}
auto n_ranges = process(space, content);

// Dump the resulting space.
unsigned n_nets = 0;
for ( auto && [ r, p] : space) {
for ( auto && net : r.networks()) {
++n_nets;
std::cout << W().print("{}\n", net);
}
}

auto delta = std::chrono::system_clock::now() - t0;

std::cout << W().print("{} ranges in, {} ranges condensed, {} networks out in {} ms\n"
, n_ranges, space.count(), n_nets
, std::chrono::duration_cast<std::chrono::milliseconds>(delta).count());

return 0;
}

0 comments on commit 40203b0

Please sign in to comment.