194 lines
5.0 KiB
C++
194 lines
5.0 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* Copyright 2022, Danny Robson <danny@nerdcruft.net>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "./converter.hpp"
|
|
#include "./ops.hpp"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
template <typename ElementT>
|
|
struct cruft::serialise::converter<std::vector<ElementT>> {
|
|
using value_type = std::vector<ElementT>;
|
|
|
|
static std::size_t
|
|
size (value_type const &val)
|
|
{
|
|
std::size_t accum = sizeof (typename value_type::size_type);
|
|
for (auto const &i: val)
|
|
accum += converter<ElementT>::size (i);
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
cruft::view<std::byte*>
|
|
to_bytes [[nodiscard]] (
|
|
cruft::view<std::byte*> dst,
|
|
value_type const &src
|
|
) {
|
|
dst = ::cruft::serialise::to_bytes (dst, src.size ());
|
|
|
|
for (auto const &i: src)
|
|
dst = ::cruft::serialise::to_bytes (dst, i);
|
|
|
|
return dst;
|
|
}
|
|
|
|
static
|
|
value_type
|
|
from_bytes (cruft::view<std::byte*> &src)
|
|
{
|
|
auto const len = ::cruft::serialise::from_bytes<typename std::vector<ElementT>::size_type> (src);
|
|
|
|
std::vector<ElementT> res;
|
|
res.reserve (len);
|
|
|
|
for (std::size_t i = 0; i != len; ++i)
|
|
res.push_back (::cruft::serialise::from_bytes<ElementT> (src));
|
|
|
|
return res;
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
template <>
|
|
struct cruft::serialise::converter<std::string> {
|
|
using value_type = std::string;
|
|
|
|
static std::size_t
|
|
size (value_type const &val)
|
|
{
|
|
return sizeof (value_type::size_type) + sizeof (value_type::value_type) * val.size ();
|
|
}
|
|
|
|
static
|
|
cruft::view<std::byte*>
|
|
to_bytes [[nodiscard]] (
|
|
cruft::view<std::byte*> dst,
|
|
value_type const &src
|
|
) {
|
|
dst = ::cruft::serialise::to_bytes (dst, src.size ());
|
|
for (auto const &i: src)
|
|
dst = ::cruft::serialise::to_bytes (dst, i);
|
|
return dst;
|
|
}
|
|
|
|
static
|
|
value_type
|
|
from_bytes (cruft::view<std::byte*> &src)
|
|
{
|
|
std::string res;
|
|
res.resize (::cruft::serialise::converter<std::string::size_type>::from_bytes (src));
|
|
for (auto &i: res)
|
|
i = ::cruft::serialise::converter<std::string::value_type>::from_bytes (src);
|
|
return res;
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
template <typename A, typename B>
|
|
struct cruft::serialise::converter<std::pair<A, B>> {
|
|
using value_type = std::pair<A, B>;
|
|
|
|
static std::size_t
|
|
size (value_type const &val)
|
|
{
|
|
return converter<A>::size (val.first) + converter<B>::size (val.second);
|
|
}
|
|
|
|
static
|
|
cruft::view<std::byte*>
|
|
to_bytes [[nodiscard]] (
|
|
cruft::view<std::byte*> dst,
|
|
value_type const &src
|
|
) {
|
|
dst = ::cruft::serialise::to_bytes (dst, src.first);
|
|
dst = ::cruft::serialise::to_bytes (dst, src.second);
|
|
return dst;
|
|
}
|
|
|
|
static
|
|
value_type
|
|
from_bytes (cruft::view<std::byte*> &src)
|
|
{
|
|
return {
|
|
cruft::serialise::converter<A>::from_bytes (src),
|
|
cruft::serialise::converter<B>::from_bytes (src),
|
|
};
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
template <typename ...ElementT>
|
|
struct cruft::serialise::converter<std::tuple<ElementT...>> {
|
|
using value_type = std::tuple<ElementT...>;
|
|
|
|
static std::size_t
|
|
size (value_type const &val)
|
|
{
|
|
return size (val, std::make_index_sequence<sizeof ...(ElementT)> {});
|
|
}
|
|
|
|
static
|
|
cruft::view<std::byte*>
|
|
to_bytes [[nodiscard]] (
|
|
cruft::view<std::byte*> dst,
|
|
value_type const &src
|
|
) {
|
|
return to_bytes (dst, src, std::make_index_sequence<sizeof... (ElementT)> {});
|
|
}
|
|
|
|
static
|
|
value_type
|
|
from_bytes (cruft::view<std::byte*> &src)
|
|
{
|
|
return from_bytes (src, std::make_index_sequence<sizeof... (ElementT)> {});
|
|
}
|
|
|
|
private:
|
|
template <std::size_t ...Index>
|
|
static std::size_t
|
|
size (value_type const &val, std::index_sequence<Index...> const &)
|
|
{
|
|
return (
|
|
converter<
|
|
std::tuple_element_t<Index, value_type>
|
|
>::size (
|
|
std::get<Index> (val)
|
|
) + ... + 0uz
|
|
);
|
|
}
|
|
|
|
|
|
template <std::size_t ...IndexV>
|
|
static
|
|
cruft::view<std::byte*>
|
|
to_bytes [[nodiscard]] (
|
|
cruft::view<std::byte*> dst,
|
|
value_type const &src,
|
|
std::index_sequence<IndexV...> const&
|
|
) {
|
|
return ::cruft::serialise::to_bytes (dst, std::get<IndexV> (src)...);
|
|
}
|
|
|
|
|
|
template <std::size_t ...IndexV>
|
|
static
|
|
value_type
|
|
from_bytes (cruft::view<std::byte*> &src, std::index_sequence<IndexV...> const&)
|
|
{
|
|
return std::tuple {
|
|
::cruft::serialise::from_bytes<ElementT> (src)...,
|
|
};
|
|
}
|
|
};
|