Commit 0304cdf9 authored by Dominik Charousset's avatar Dominik Charousset

Provide new suffix + prefix ctor

parent 05f89978
......@@ -20,6 +20,7 @@
#include <array>
#include <cstdint>
#include <initializer_list>
#include <string>
#include "caf/byte_address.hpp"
......@@ -41,12 +42,22 @@ public:
using array_type = std::array<uint8_t, num_bytes>;
using uint16_ilist = std::initializer_list<uint16_t>;
// -- constructors, destructors, and assignment operators --------------------
/// Constructs an all-zero address.
ipv6_address();
/// Constructs an address from given prefix and suffix.
/// @pre `prefix.size() + suffix.size() <= 8`
/// @warning assumes network byte order for prefix and suffix
ipv6_address(uint16_ilist prefix, uint16_ilist suffix);
/// Embeds an IPv4 address into an IPv6 address.
explicit ipv6_address(ipv4_address addr);
/// Constructs an IPv6 address from given bytes.
explicit ipv6_address(array_type bytes);
// -- comparison -------------------------------------------------------------
......
......@@ -86,6 +86,26 @@ ipv6_address::ipv6_address() {
half_segments_[1] = 0;
}
ipv6_address::ipv6_address(uint16_ilist prefix, uint16_ilist suffix) {
CAF_ASSERT((prefix.size() + suffix.size()) <= 8);
auto addr_fill = [&](uint16_ilist chunks) {
union {
uint16_t i;
std::array<uint8_t, 2> a;
} tmp;
size_t p = 0;
for (auto chunk : chunks) {
tmp.i = detail::to_network_order(chunk);
bytes_[p++] = tmp.a[0];
bytes_[p++] = tmp.a[1];
}
};
bytes_.fill(0);
addr_fill(suffix);
std::rotate(bytes_.begin(), bytes_.begin() + suffix.size() * 2, bytes_.end());
addr_fill(prefix);
}
ipv6_address::ipv6_address(ipv4_address addr) {
std::copy(v4_prefix.begin(), v4_prefix.end(), quad_segments_.begin());
quad_segments_.back() = addr.bits();
......
......@@ -32,36 +32,9 @@ namespace {
using array_type = ipv6_address::array_type;
void addr_fill(ipv6_address::array_type& arr,
std::initializer_list<uint16_t> chunks) {
union {
uint16_t i;
std::array<uint8_t, 2> a;
} tmp;
size_t p = 0;
for (auto chunk : chunks) {
tmp.i = detail::to_network_order(chunk);
arr[p++] = tmp.a[0];
arr[p++] = tmp.a[1];
}
}
ipv6_address addr(std::initializer_list<uint16_t> prefix,
std::initializer_list<uint16_t> suffix) {
CAF_ASSERT((prefix.size() + suffix.size()) <= 8);
ipv6_address::array_type bytes;
bytes.fill(0);
addr_fill(bytes, suffix);
std::rotate(bytes.begin(), bytes.begin() + suffix.size() * 2, bytes.end());
addr_fill(bytes, prefix);
return ipv6_address{bytes};
}
ipv6_address addr(std::initializer_list<uint16_t> segments) {
ipv6_address::array_type bytes;
bytes.fill(0);
addr_fill(bytes, segments);
return ipv6_address{bytes};
std::initializer_list<uint16_t> suffix = {}) {
return ipv6_address{prefix, suffix};
}
} // namespace <anonymous>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment