30 #ifndef TINS_MEMORY_HELPERS_H 31 #define TINS_MEMORY_HELPERS_H 36 #include <tins/exceptions.h> 37 #include <tins/endianness.h> 51 inline void read_data(
const uint8_t* buffer, uint8_t* output_buffer,
size_t size) {
52 std::memcpy(output_buffer, buffer, size);
56 void read_value(
const uint8_t* buffer, T& value) {
57 std::memcpy(&value, buffer,
sizeof(value));
60 inline void write_data(uint8_t* buffer,
const uint8_t* ptr,
size_t size) {
61 std::memcpy(buffer, ptr, size);
65 void write_value(uint8_t* buffer,
const T& value) {
66 std::memcpy(buffer, &value,
sizeof(value));
69 class InputMemoryStream {
71 InputMemoryStream(
const uint8_t* buffer,
size_t total_sz)
72 : buffer_(buffer), size_(total_sz) {
75 InputMemoryStream(
const std::vector<uint8_t>& data) : buffer_(&data[0]), size_(data.size()) {
87 return Endian::le_to_host(read<T>());
92 return Endian::be_to_host(read<T>());
97 if (!can_read(
sizeof(value))) {
98 throw malformed_packet();
100 read_value(buffer_, value);
104 void skip(
size_t size) {
105 if (TINS_UNLIKELY(size > size_)) {
106 throw malformed_packet();
112 bool can_read(
size_t byte_count)
const {
113 return TINS_LIKELY(size_ >= byte_count);
116 void read(
void* output_buffer,
size_t output_buffer_size) {
117 if (!can_read(output_buffer_size)) {
118 throw malformed_packet();
120 read_data(buffer_, (uint8_t*)output_buffer, output_buffer_size);
121 skip(output_buffer_size);
124 const uint8_t* pointer()
const {
128 size_t size()
const {
132 void size(
size_t new_size) {
136 operator bool()
const {
140 void read(std::vector<uint8_t>& value,
size_t count);
141 void read(HWAddress<6>& address);
142 void read(IPv4Address& address);
143 void read(IPv6Address& address);
145 const uint8_t* buffer_;
149 class OutputMemoryStream {
151 OutputMemoryStream(uint8_t* buffer,
size_t total_sz)
152 : buffer_(buffer), size_(total_sz) {
155 OutputMemoryStream(std::vector<uint8_t>& buffer)
156 : buffer_(&buffer[0]), size_(buffer.size()) {
159 template <
typename T>
160 void write(
const T& value) {
161 if (TINS_UNLIKELY(size_ <
sizeof(value))) {
162 throw serialization_error();
164 write_value(buffer_, value);
168 template <
typename T>
169 void write_be(
const T& value) {
170 write(Endian::host_to_be(value));
173 template <
typename T>
174 void write_le(
const T& value) {
175 write(Endian::host_to_le(value));
178 template <
typename ForwardIterator>
179 void write(ForwardIterator start, ForwardIterator end) {
180 const size_t length = std::distance(start, end);
181 if (TINS_UNLIKELY(size_ < length)) {
182 throw serialization_error();
185 if (TINS_UNLIKELY(length == 0)) {
188 std::memcpy(buffer_, &*start, length);
192 void skip(
size_t size) {
193 if (TINS_UNLIKELY(size > size_)) {
194 throw malformed_packet();
200 void write(
const uint8_t* ptr,
size_t length) {
201 write(ptr, ptr + length);
204 void fill(
size_t size, uint8_t value) {
205 if (TINS_UNLIKELY(size_ < size)) {
206 throw serialization_error();
208 std::memset(buffer_, value, size);
216 size_t size()
const {
220 void write(
const HWAddress<6>& address);
221 void write(
const IPv4Address& address);
222 void write(
const IPv6Address& address);
235 #endif // TINS_MEMORY_HELPERS_H The Tins namespace.
Definition: address_range.h:38