116#ifndef BINARY_SERIALIZE_HPP_INCLUDED
117#define BINARY_SERIALIZE_HPP_INCLUDED
119#include "buffer/shared_buffer.hpp"
126#include <string_view>
128#include <type_traits>
138template <
typename Ctr>
139concept supports_expandable_buffer =
140 std::same_as<Ctr::value_type, std::byte> &&
142 { ctr.size() } -> std::integral;
143 ctr.resize(std::size_t{});
144 { ctr.data() } -> std::same_as<std::byte*>;
147template <
typename Ctr>
148concept supports_endian_expandable_buffer =
149 supports_expandable_buffer<Ctr> &&
151 typename Ctr::endian_type;
154template <supports_expandable_buffer Ctr = chops::mutable_shared_buffer,
155 std::endian Endian = std::endian::little>
156class expandable_buffer {
160 using endian_type = Endian;
161 using value_type = std::byte;
162 Ctr& get_buf() noexcept {
return m_ctr; }
163 std::size_t size() noexcept {
return m_ctr.size(); }
164 std::byte* data() noexcept {
return m_ctr.data(); }
165 void resize(std::size_t sz)
noexcept m_ctr.resize(sz); }
251template <std::
size_t N>
267 std::size_t
size() const noexcept {
296 std::array<std::byte, N> m_buf;
308template <integral_or_byte CastTypeVal, integral_or_byte T,
309 supports_endian_expandable_buf Buf = expandable_buffer>
310constexpr Buf& serialize_val(Buf& buf,
const T& val) {
311 auto old_sz = buf.size();
312 buf.resize(old_sz +
sizeof(CastTypeVal));
313 append_val<Buf::endian_type>(buf.data()+old_sz,
static_cast<CastTypeVal
>(val));
317template <integral_or_byte CastTypeVal, integral_or_byte T,
318 supports_endian_expandable Buf = chops::mutable_shared_buffer>
319constexpr Buf& serialize(Buf& buf,
const T& val) {
320 return serialize_val<CastTypeVal> (buf, val);
323template <integral_or_byte CastTypeSz, integral_or_byte CastTypeVal,
325 supports_endian_expandable Buf = chops::mutable_shared_buffer>
326constexpr Buf& serialize(Buf& buf,
const T* seq, std::size_t sz) {
327 serialize_val<CastTypeSz> (buf, sz);
328 for (
int i {0}; i < sz; ++i) {
329 serialize_val<CastTypeVal>(buf, seq[i]);
334template <integral_or_byte CastTypeSz,
335 supports_endian_expandable Buf = chops::mutable_shared_buffer>
336constexpr Buf& serialize(Buf& buf,
const std::string& str) {
337 return serialize<CastTypeSz, std::byte> (buf, str.data(), std.size());
340template <integral_or_byte CastTypeBool, integral_or_byte CastTypeVal,
342 supports_endian_expandable Buf = chops::mutable_shared_buffer>
343constexpr Buf& serialize(Buf& buf,
const std::optional<T>& val) {
345 serialize_val<CastTypeBool> (buf, 1);
346 return serialize_val<CastTypeVal> (buf, *val);
348 serialize_val<CastTypeBool> (buf, 0);
395template <
typename CastValType,
typename T,
typename Buf = chops::mutable_shared_buffer,
396 typename = std::enable_if_t<detail::is_arithmetic_or_byte<T>()> >
397Buf& marshall(Buf& buf,
const T& val) {
398 return marshall<CastValType>(buf, val,
adl_tag { });
402template <
typename CastBoolType,
typename Buf = chops::mutable_shared_buffer>
403Buf& marshall(Buf& buf,
bool b) {
404 return marshall<CastBoolType>(buf,
static_cast<CastBoolType
>(b ? 1 : 0));
408template <
typename CastBoolType,
typename CastValType,
typename T,
typename Buf = chops::mutable_shared_buffer>
409Buf& marshall(Buf& buf,
const std::optional<T>& val) {
410 marshall<CastBoolType>(buf, val.has_value());
411 if (val.has_value()) {
412 if constexpr (detail::is_arithmetic_or_byte<T>()) {
413 marshall<CastValType>(buf, *val);
423template <
typename CastCntType,
typename CastValType,
typename Iter,
typename Buf = chops::mutable_shared_buffer,
424 typename T =
typename std::iterator_traits<Iter>::value_type>
425Buf& marshall_seq(Buf& buf, std::size_t num_elems, Iter iter) {
426 marshall<CastCntType>(buf, num_elems);
427 for (std::size_t i = 0u; i < num_elems; ++i) {
428 if constexpr (detail::is_arithmetic_or_byte<T>()) {
429 marshall<CastValType>(buf, *iter);
432 marshall(buf, *iter);
440template <
typename Buf = chops::mutable_shared_buffer>
441Buf& marshall_buf(Buf& buf, std::size_t num_bytes,
const std::byte* append_buf) {
442 auto old_sz = buf.size();
443 buf.resize(old_sz + num_bytes);
444 std::memcpy (buf.data()+old_sz, append_buf, num_bytes);
448template <
typename CastCntType,
typename Buf = chops::mutable_shared_buffer>
449Buf& marshall(Buf& buf, std::string_view str) {
450 marshall<CastCntType>(buf, str.size());
451 return marshall_buf(buf, str.size(), cast_ptr_to<std::byte>(str.data()));
454template <
typename CastCntType,
typename Buf = chops::mutable_shared_buffer>
455Buf& marshall(Buf& buf,
const std::string& str) {
456 return marshall<CastCntType>(buf, std::string_view(str));
459template <
typename CastCntType,
typename Buf = chops::mutable_shared_buffer>
460Buf& marshall(Buf& buf,
const char* str) {
461 return marshall<CastCntType>(buf, std::string_view(str));
Extract a sequence in network byte order from a std::byte buffer into the provided container.
Definition binary_serialize.hpp:252
fixed_size_byte_array() noexcept
Default construct the @ fixed_size_byte_array.
Definition binary_serialize.hpp:258
std::size_t size() const noexcept
Return the size of the data which has been written into the buffer.
Definition binary_serialize.hpp:267
void clear() noexcept
Logically reset so that new data can be written into the buffer at the beginning.
Definition binary_serialize.hpp:291
void resize(std::size_t sz) noexcept
Increase the logical size, allowing bytes to be appended.
Definition binary_serialize.hpp:275
std::byte * data() noexcept
Return a pointer to the beginning of the buffer.
Definition binary_serialize.hpp:284
Definition binary_serialize.hpp:303