/* * Copyright 2016 ScyllaDB */ /* * This file is part of Scylla. * * Scylla is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Scylla is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Scylla. If not, see . */ #pragma once #include "serializer.hh" namespace ser { template void set_size(seastar::simple_output_stream& os, const T& obj) { serialize(os, get_sizeof(obj)); } template void set_size(seastar::measuring_output_stream& os, const T& obj) { serialize(os, uint32_t(0)); } template void safe_serialize_as_uint32(Output& out, uint64_t data) { if (data > std::numeric_limits::max()) { throw std::runtime_error("Size is too big for serialization"); } serialize(out, uint32_t(data)); } template inline void serialize(Output& out, const std::vector& v) { safe_serialize_as_uint32(out, v.size()); for (auto&& e : v) { serialize(out, e); } } template inline std::vector deserialize(Input& in, boost::type>) { auto sz = deserialize(in, boost::type()); std::vector v; v.reserve(sz); while (sz--) { v.push_back(deserialize(in, boost::type())); } return v; } template inline void serialize(Output& out, const std::map& v) { safe_serialize_as_uint32(out, v.size()); for (auto&& e : v) { serialize(out, e.first); serialize(out, e.second); } } template inline std::map deserialize(Input& in, boost::type>) { auto sz = deserialize(in, boost::type()); std::map m; while (sz--) { K k = deserialize(in, boost::type()); V v = deserialize(in, boost::type()); m[k] = v; } return m; } template void serialize(Output& out, const bytes_view& v) { safe_serialize_as_uint32(out, uint32_t(v.size())); out.write(reinterpret_cast(v.begin()), v.size()); } template void serialize(Output& out, const managed_bytes& v) { safe_serialize_as_uint32(out, uint32_t(v.size())); out.write(reinterpret_cast(v.begin()), v.size()); } template void serialize(Output& out, const bytes& v) { safe_serialize_as_uint32(out, uint32_t(v.size())); out.write(reinterpret_cast(v.begin()), v.size()); } template bytes deserialize(Input& in, boost::type) { auto sz = deserialize(in, boost::type()); bytes v(bytes::initialized_later(), sz); in.read(reinterpret_cast(v.begin()), sz); return v; } template void serialize(Output& out, const bytes_ostream& v) { safe_serialize_as_uint32(out, uint32_t(v.size())); for (bytes_view frag : v.fragments()) { out.write(reinterpret_cast(frag.begin()), frag.size()); } } template bytes_ostream deserialize(Input& in, boost::type) { bytes_ostream v; v.write(deserialize(in, boost::type())); return v; } template inline void serialize(Output& out, const std::experimental::optional& v) { serialize(out, bool(v)); if (v) { serialize(out, v.value()); } } template inline std::experimental::optional deserialize(Input& in, boost::type>) { std::experimental::optional v; auto b = deserialize(in, boost::type()); if (b) { v = deserialize(in, boost::type()); } return v; } template void serialize(Output& out, const sstring& v) { safe_serialize_as_uint32(out, uint32_t(v.size())); out.write(v.begin(), v.size()); } template sstring deserialize(Input& in, boost::type) { auto sz = deserialize(in, boost::type()); sstring v(sstring::initialized_later(), sz); in.read(v.begin(), sz); return v; } template inline void serialize(Output& out, const std::unique_ptr& v) { serialize(out, bool(v)); if (v) { serialize(out, *v); } } template inline std::unique_ptr deserialize(Input& in, boost::type>) { std::unique_ptr v; auto b = deserialize(in, boost::type()); if (b) { v = std::make_unique(deserialize(in, boost::type())); } return v; } template inline void serialize(Output& out, const std::chrono::time_point& v) { serialize(out, uint64_t(v.time_since_epoch().count())); } template inline std::chrono::time_point deserialize(Input& in, boost::type>) { return typename Clock::time_point(Duration(deserialize(in, boost::type()))); } template inline void serialize(Output& out, const enum_set& v) { serialize(out, uint64_t(v.mask())); } template inline enum_set deserialize(Input& in, boost::type>) { return enum_set::from_mask(deserialize(in, boost::type())); } template size_type get_sizeof(const T& obj) { seastar::measuring_output_stream ms; serialize(ms, obj); auto size = ms.size(); if (size > std::numeric_limits::max()) { throw std::runtime_error("Object is too big for get_sizeof"); } return size; } template Buffer serialize_to_buffer(const T& v, size_t head_space) { seastar::measuring_output_stream measure; ser::serialize(measure, v); Buffer ret(typename Buffer::initialized_later(), measure.size() + head_space); seastar::simple_output_stream out(reinterpret_cast(ret.begin()), head_space); ser::serialize(out, v); return ret; } }