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");
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 ) 169 TEST(Span, MutableConstruction)
171 struct no_conversion{};
172 struct inherited : no_conversion {};
201 TEST(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}},
326 epee::to_byte_span<char>(expected)
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);
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;
434 const std::vector<unsigned char> all_bytes = get_all_bytes();
436 expected.append(std_to_hex(all_bytes));
443 std::stringstream out;
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]; };
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)
500 if ((i >=
'0' && i <=
'9') || (i >=
'A' && i <=
'F') || (i >=
'a' && i <=
'f')) {
566 TEST(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);
576 EXPECT_STREQ(
"51.0.18.255:65535", address1.str().c_str());
577 EXPECT_STREQ(
"51.0.18.255", address1.host_str().c_str());
609 EXPECT_STREQ(
"51.0.18.255", address2.host_str().c_str());
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; }
651 constexpr
static bool is_blockable() noexcept {
return false; }
676 EXPECT_STREQ(
"51.0.18.255:65535", address1.str().c_str());
677 EXPECT_STREQ(
"51.0.18.255", address1.host_str().c_str());
684 EXPECT_THROW(address1.as<custom_address>(), std::bad_cast);
722 EXPECT_STREQ(
"51.0.18.255", address2.host_str().c_str());
730 EXPECT_STREQ(
"51.0.18.255:65535", address2.str().c_str());
731 EXPECT_STREQ(
"51.0.18.255", address2.host_str().c_str());
746 std::stringstream stream;
761 address1 = custom_address{};
770 static 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);
830 TEST(net_buffer, existing_capacity)
834 buf.append(
"123456789", 9);
836 buf.append(
"abc", 3);
837 buf.append(
"def", 3);
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;
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
const CharType(& source)[N]
#define EXPECT_NO_THROW(statement)
span< const std::uint8_t > as_byte_span(const T &src) noexcept
#define EXPECT_TRUE(condition)
#define EXPECT_STREQ(s1, s2)
constexpr const_iterator cbegin() const noexcept
#define EXPECT_THROW(statement, expected_exception)
static std::array< char, N *2 > array(const std::array< std::uint8_t, N > &src) noexcept
span< std::uint8_t > as_mut_byte_span(T &src) noexcept
Non-owning sequence of data. Does not deep copy.
#define CHECK_LESS_ENDIAN(lhs, rhs)
#define ASSERT_FALSE(condition)
constexpr std::size_t size() const noexcept
#define ASSERT_EQ(val1, val2)
constexpr span< typename T::value_type > to_mut_span(T &src)
mdb_size_t count(MDB_cursor *cur)
#define CHECK_EQUAL(lhs, rhs)
constexpr const_iterator cend() const noexcept
static std::vector< uint8_t > vector(boost::string_ref src)
const_pointer const_iterator
int less(MDB_val const *left, MDB_val const *right) noexcept
static constexpr address_type get_type_id() noexcept
constexpr iterator end() const noexcept
boost::endian::big_uint32_t ip
bool is_ip_local(uint32_t ip)
constexpr span< const typename T::value_type > to_span(const T &src)
const T & move(const T &t)
static void buffer(std::ostream &out, const span< const std::uint8_t > src)
Append src as hex to out.
const GenericPointer< typename T::ValueType > T2 value
#define ASSERT_TRUE(condition)
const T & const_reference
static std::string string(const span< const std::uint8_t > src)
#define CHECK_LESS(lhs, rhs)
constexpr iterator begin() const noexcept
constexpr std::size_t size_bytes() const noexcept
#define EXPECT_FALSE(condition)
bool match_number(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, boost::string_ref &val)
constexpr bool empty() const noexcept
#define EXPECT_EQ(val1, val2)
static void formatted(std::ostream &out, const span< const std::uint8_t > src)
Append < + src + > as hex to out.
std::ptrdiff_t difference_type
span< const std::uint8_t > to_byte_span(const span< const T > src) noexcept
constexpr pointer data() const noexcept