31#include <boost/endian/conversion.hpp>
32#include <boost/range/algorithm/equal.hpp>
33#include <boost/range/algorithm_ext/iota.hpp>
35#include <gtest/gtest.h>
42# include <arpa/inet.h>
58 template<
typename Destination,
typename Source>
61 const unsigned count =
62 unsigned(std::is_constructible<Destination, Source>()) +
63 unsigned(std::is_constructible<Destination, Source&>()) +
64 unsigned(std::is_convertible<Source, Destination>()) +
65 unsigned(std::is_convertible<Source&, Destination>()) +
66 unsigned(std::is_assignable<Destination, Source>()) +
67 unsigned(std::is_assignable<Destination, Source&>());
69 "Mismatch on construction results - " <<
count <<
" were true";
75 static_assert(!test_string.empty(),
"test failure");
76 static_assert(test_string.size() == 9,
"test failure");
77 static_assert(test_string.size_bytes() == 9,
"test_failure");
78 static_assert(test_string.begin() == test_string.cbegin(),
"test failure");
79 static_assert(test_string.end() == test_string.cend(),
"test failure");
80 static_assert(test_string.cend() - test_string.cbegin() == 9,
"test failure");
81 static_assert(*test_string.cbegin() ==
'a',
"test failure");
82 static_assert(*(test_string.cend() - 2) ==
'g',
"test failure");
92 std::string std_to_hex(
const std::vector<unsigned char>&
source)
94 std::stringstream
out;
96 for (
const unsigned char byte :
source)
98 out << std::setw(2) << std::setfill(
'0') << int(
byte);
103 std::vector<unsigned char> get_all_bytes()
105 std::vector<unsigned char>
out;
107 boost::range::iota(out, 0);
111 #define CHECK_EQUAL(lhs, rhs) \
112 EXPECT_TRUE( lhs == rhs ); \
113 EXPECT_TRUE( rhs == lhs ); \
114 EXPECT_FALSE( lhs != rhs ); \
115 EXPECT_FALSE( rhs != lhs ); \
116 EXPECT_FALSE( lhs < rhs ); \
117 EXPECT_FALSE( rhs < lhs ); \
118 EXPECT_TRUE( lhs <= rhs ); \
119 EXPECT_TRUE( rhs <= lhs ); \
120 EXPECT_FALSE( lhs > rhs ); \
121 EXPECT_FALSE( rhs > lhs ); \
122 EXPECT_TRUE( lhs >= rhs ); \
123 EXPECT_TRUE( rhs >= lhs )
125 #define CHECK_LESS(lhs, rhs) \
126 EXPECT_FALSE( lhs == rhs ); \
127 EXPECT_FALSE( rhs == lhs ); \
128 EXPECT_TRUE( lhs != rhs ); \
129 EXPECT_TRUE( rhs != lhs ); \
130 EXPECT_TRUE( lhs < rhs ); \
131 EXPECT_FALSE( rhs < lhs ); \
132 EXPECT_TRUE( lhs <= rhs ); \
133 EXPECT_FALSE( rhs <= lhs ); \
134 EXPECT_FALSE( lhs > rhs ); \
135 EXPECT_TRUE( rhs > lhs ); \
136 EXPECT_FALSE( lhs >= rhs ); \
137 EXPECT_TRUE( rhs >= lhs )
139 #ifdef BOOST_LITTLE_ENDIAN
140 #define CHECK_LESS_ENDIAN(lhs, rhs) CHECK_LESS( rhs , lhs )
142 #define CHECK_LESS_ENDIAN(lhs, rhs) CHECK_LESS( lhs , rhs )
171 struct no_conversion{};
172 struct inherited : no_conversion {};
201TEST(Span, ImmutableConstruction)
203 struct no_conversion{};
204 struct inherited : no_conversion {};
275 check_empty(
nullptr);
280 const int expected[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
294 boost::range::iota(span, -5);
303 const std::array<unsigned, 4> expected{0, 1, 2, 3};
306 EXPECT_EQ(expected.begin(), span.begin());
310 EXPECT_EQ(expected.begin() + 2, span.begin());
322 const char expected[] = {56, 44, 11, 5};
325 std::array<std::uint8_t, 4>{{56, 44, 11, 5}},
331 std::array<char, 4>{{56, 44, 11, 5}},
339 struct some_pod {
char value[4]; };
340 const some_pod immutable {{ 5, 10, 12, 127 }};
343 std::array<unsigned char, 4>{{5, 10, 12, 127}},
356 struct some_pod {
char value[4]; };
360 boost::range::iota(span, 1);
363 std::array<unsigned char, 4>{{1, 2, 3, 4}}, actual.value
370 std::vector<unsigned> mut;
374 boost::range::iota(span, 1);
375 EXPECT_EQ((std::vector<unsigned>{1, 2, 3, 4}), mut);
382 std::string{
"ffab0100"},
386 const std::vector<unsigned char> all_bytes = get_all_bytes();
396 std::vector<uint8_t>
source{{ 0x00, 0xFF, 0x0F, 0xF0 }};
408 hex.assign(
"00:ff 0f:f0");
415 (std::array<char, 8>{{
'f',
'f',
'a',
'b',
'0',
'1',
'0',
'0'}}),
422 std::stringstream out;
427 const std::uint8_t
source[] = {0xff, 0xab, 0x01, 0x00};
431 std::string expected{
"ffab0100"};
434 const std::vector<unsigned char> all_bytes = get_all_bytes();
436 expected.append(std_to_hex(all_bytes));
443 std::stringstream out;
444 std::string expected{
"<>"};
449 expected.append(
"<ffab0100>");
453 const std::vector<unsigned char> all_bytes = get_all_bytes();
455 expected.append(
"<").append(std_to_hex(all_bytes)).append(
">");
462 const std::vector<unsigned char> all_bytes = get_all_bytes();
465 std_to_hex(all_bytes),
467 std::string{
reinterpret_cast<const char*
>(all_bytes.data()), all_bytes.size()}
474 struct some_pod {
unsigned char data[4]; };
476 std::string{
"ffab0100"},
483 static const char data[] =
"a10b68c2";
484 for (
size_t i = 0; i <
sizeof(data); i += 2)
490 ASSERT_EQ(memcmp(data, hex.data(), i), 0);
497 for (
size_t i = 0; i < 256; ++i)
499 std::string inputHexString = std::string(2,
static_cast<char>(i));
500 if ((i >=
'0' && i <=
'9') || (i >=
'A' && i <=
'F') || (i >=
'a' && i <=
'f')) {
516 std::string{
"255.0.255.0"},
520 std::string{
"255.255.255.255"},
527 std::uint32_t ip = 0;
566TEST(NetUtils, IPv4NetworkAddress)
570 const auto ip1 = boost::endian::native_to_big(0x330012FFu);
571 const auto ip_loopback = boost::endian::native_to_big(0x7F000001u);
572 const auto ip_local = boost::endian::native_to_big(0x0A000000u);
612 address2 = std::move(address1);
620 std::stringstream stream;
637 const auto ip1 = boost::endian::native_to_big(0x330012FFu);
638 const auto ip_loopback = boost::endian::native_to_big(0x7F000001u);
639 const auto ip_local = boost::endian::native_to_big(0x0A000000u);
641 struct custom_address {
642 constexpr static bool equal(
const custom_address&)
noexcept {
return false; }
643 constexpr static bool less(
const custom_address&)
noexcept {
return false; }
644 constexpr static bool is_same_host(
const custom_address&)
noexcept {
return false; }
645 constexpr static bool is_loopback()
noexcept {
return false; }
646 constexpr static bool is_local()
noexcept {
return false; }
647 static std::string str() {
return {}; }
648 static std::string host_str() {
return {}; }
651 constexpr static bool is_blockable()
noexcept {
return false; }
665 EXPECT_THROW(empty.as<custom_address>(), std::bad_cast);
724 address2 = std::move(address1);
746 std::stringstream stream;
761 address1 = custom_address{};
770static bool is_local(
const char *s)
782 ASSERT_EQ(is_local(
"192.167.255.255"),
false);
783 ASSERT_EQ(is_local(
"192.168.0.0"),
true);
784 ASSERT_EQ(is_local(
"192.168.255.255"),
true);
785 ASSERT_EQ(is_local(
"192.169.0.0"),
false);
787 ASSERT_EQ(is_local(
"172.15.255.255"),
false);
789 ASSERT_EQ(is_local(
"172.16.255.255"),
true);
790 ASSERT_EQ(is_local(
"172.31.255.255"),
true);
791 ASSERT_EQ(is_local(
"172.32.0.0"),
false);
793 ASSERT_EQ(is_local(
"255.255.255.254"),
false);
794 ASSERT_EQ(is_local(
"11.255.255.255"),
false);
796 ASSERT_EQ(is_local(
"0.0.168.192"),
false);
797 ASSERT_EQ(is_local(
"0.0.30.172"),
false);
798 ASSERT_EQ(is_local(
"0.0.30.127"),
false);
830TEST(net_buffer, existing_capacity)
834 buf.append(
"123456789", 9);
836 buf.append(
"abc", 3);
837 buf.append(
"def", 3);
847 buf.append(std::string(4000,
' ').c_str(), 4000);
848 buf.append(std::string(8000,
'0').c_str(), 8000);
851 ASSERT_TRUE(!memcmp(span.
data(), std::string(4000,
' ').c_str(), 4000));
852 ASSERT_TRUE(!memcmp(span.
data() + 4000, std::string(8000,
'0').c_str(), 8000));
859 buf.append(std::string(400,
' ').c_str(), 400);
861 buf.append(std::string(4000,
'0').c_str(), 4000);
865 ASSERT_TRUE(!memcmp(span.
data() + 1, std::string(4000,
'0').c_str(), 4000));
871 for (
int c = 1; c < 256; ++c)
880 for (
int c = 1; c < 256; ++c)
888 boost::string_ref val;
890 std::string::const_iterator i;
static constexpr address_type get_type_id() noexcept
constexpr uint16_t port() const noexcept
constexpr uint32_t ip() const noexcept
std::string host_str() const
address_type get_type_id() const
bool is_same_host(const network_address &other) const
std::string host_str() const
bool is_blockable() const
Non-owning sequence of data. Does not deep copy.
const T & const_reference
constexpr const_iterator cend() const noexcept
constexpr std::size_t size_bytes() const noexcept
constexpr iterator end() const noexcept
constexpr std::size_t size() const noexcept
std::ptrdiff_t difference_type
constexpr const_iterator cbegin() const noexcept
const_pointer const_iterator
constexpr bool empty() const noexcept
constexpr iterator begin() const noexcept
constexpr pointer data() const noexcept
#define CHECK_LESS(lhs, rhs)
#define CHECK_LESS_ENDIAN(lhs, rhs)
#define CHECK_EQUAL(lhs, rhs)
#define ASSERT_EQ(val1, val2)
#define EXPECT_NO_THROW(statement)
#define EXPECT_EQ(val1, val2)
#define EXPECT_THROW(statement, expected_exception)
#define ASSERT_FALSE(condition)
#define EXPECT_TRUE(condition)
#define EXPECT_STREQ(s1, s2)
#define TEST(test_case_name, test_name)
#define ASSERT_TRUE(condition)
#define EXPECT_FALSE(condition)
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
bool match_number(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, boost::string_ref &val)
bool is_ip_local(uint32_t ip)
span< std::uint8_t > as_mut_byte_span(T &src) noexcept
span< const std::uint8_t > to_byte_span(const span< const T > src) noexcept
constexpr span< const typename T::value_type > to_span(const T &src)
span< const std::uint8_t > as_byte_span(const T &src) noexcept
constexpr span< typename T::value_type > to_mut_span(T &src)
mdb_size_t count(MDB_cursor *cur)
const GenericPointer< typename T::ValueType > T2 value
const CharType(& source)[N]
static std::vector< uint8_t > vector(boost::string_ref src)
static std::array< char, N *2 > array(const std::array< std::uint8_t, N > &src) noexcept
static std::string string(const span< const std::uint8_t > src)
static void formatted(std::ostream &out, const span< const std::uint8_t > src)
Append < + src + > as hex to out.
static void buffer(std::ostream &out, const span< const std::uint8_t > src)
Append src as hex to out.