28 #ifndef GU_SERIALIZE_HPP
29 #define GU_SERIALIZE_HPP
31 #include "gu_throw.hpp"
32 #include "gu_byteswap.hpp"
33 #include "gu_buffer.hpp"
34 #include "gu_macros.hpp"
41 inline size_t serial_size(
const T& t)
42 {
return t.serial_size(); }
45 inline size_t serial_size(
const uint8_t& b)
49 inline size_t serial_size(
const uint16_t& b)
53 inline size_t serial_size(
const uint32_t& b)
57 inline size_t serial_size(
const uint64_t& b)
61 template <
typename TO,
typename FROM>
63 __private_serialize(
const FROM& f,
void*
const buf,
size_t const buflen,
66 GU_COMPILE_ASSERT(std::numeric_limits<TO>::is_integer, not_integer1);
67 GU_COMPILE_ASSERT(std::numeric_limits<FROM>::is_integer, not_integer2);
68 GU_COMPILE_ASSERT(
sizeof(FROM) ==
sizeof(TO), size_differs);
69 size_t const ret = offset +
sizeof(TO);
70 if (gu_unlikely(ret > buflen))
72 gu_throw_error(EMSGSIZE) << ret <<
" > " << buflen;
74 void*
const pos(reinterpret_cast<byte_t*>(buf) + offset);
75 *
reinterpret_cast<TO*
>(pos) = htog<TO>(f);
80 template <
typename FROM,
typename TO>
82 __private_unserialize(
const void*
const buf,
size_t const buflen,
83 size_t const offset, TO& t)
85 GU_COMPILE_ASSERT(std::numeric_limits<TO>::is_integer, not_integer1);
86 GU_COMPILE_ASSERT(std::numeric_limits<FROM>::is_integer, not_integer2);
87 GU_COMPILE_ASSERT(
sizeof(FROM) ==
sizeof(TO), size_differs);
88 size_t const ret = offset +
sizeof(t);
89 if (gu_unlikely(ret > buflen))
91 gu_throw_error(EMSGSIZE) << ret <<
" > " << buflen;
93 const void*
const pos(reinterpret_cast<const byte_t*>(buf) + offset);
94 t = gtoh<FROM>(*
reinterpret_cast<const FROM*
>(pos));
99 GU_FORCE_INLINE
size_t serialize1(
const T& t,
104 return __private_serialize<uint8_t>(t, buf, buflen, offset);
107 template <
typename T>
108 GU_FORCE_INLINE
size_t unserialize1(
const void*
const buf,
113 return __private_unserialize<uint8_t>(buf, buflen, offset, t);
116 template <
typename T>
117 GU_FORCE_INLINE
size_t serialize2(
const T& t,
122 return __private_serialize<uint16_t>(t, buf, buflen, offset);
125 template <
typename T>
126 GU_FORCE_INLINE
size_t unserialize2(
const void*
const buf,
131 return __private_unserialize<uint16_t>(buf, buflen, offset, t);
134 template <
typename T>
135 GU_FORCE_INLINE
size_t serialize4(
const T& t,
140 return __private_serialize<uint32_t>(t, buf, buflen, offset);
143 template <
typename T>
144 GU_FORCE_INLINE
size_t unserialize4(
const void*
const buf,
149 return __private_unserialize<uint32_t>(buf, buflen, offset, t);
152 template <
typename T>
153 GU_FORCE_INLINE
size_t serialize8(
const T& t,
158 return __private_serialize<uint64_t>(t, buf, buflen, offset);
161 template <
typename T>
162 GU_FORCE_INLINE
size_t unserialize8(
const void*
const buf,
167 return __private_unserialize<uint64_t>(buf, buflen, offset, t);
170 template <
typename ST>
171 inline size_t __private_serial_size(
const Buffer& sb)
173 GU_COMPILE_ASSERT(std::numeric_limits<ST>::is_integer, must_be_integer);
174 if (sb.size() > std::numeric_limits<ST>::max())
175 gu_throw_error(ERANGE) << sb.size() <<
" unrepresentable in "
176 <<
sizeof(ST) <<
" bytes.";
177 return sizeof(ST) + sb.size();
180 GU_FORCE_INLINE
size_t serial_size1(
const Buffer& sb)
182 return __private_serial_size<uint8_t>(sb);
185 GU_FORCE_INLINE
size_t serial_size2(
const Buffer& sb)
187 return __private_serial_size<uint16_t>(sb);
190 GU_FORCE_INLINE
size_t serial_size4(
const Buffer& sb)
192 return __private_serial_size<uint32_t>(sb);
195 GU_FORCE_INLINE
size_t serial_size8(
const Buffer& sb)
197 return __private_serial_size<uint64_t>(sb);
200 template <
typename ST>
201 inline size_t __private_serialize(
const Buffer& b,
206 size_t const ret = offset + __private_serial_size<ST>(b);
210 gu_throw_error(EMSGSIZE) << ret <<
" > " << buflen;
213 offset = __private_serialize<ST>(
static_cast<ST
>(b.size()),
214 buf, buflen, offset);
215 copy(b.begin(), b.end(),
reinterpret_cast<byte_t*
>(buf) + offset);
219 template <
typename ST>
220 inline size_t __private_unserialize(
const void*
const buf,
225 GU_COMPILE_ASSERT(std::numeric_limits<ST>::is_integer, must_be_integer);
227 size_t ret = offset +
sizeof(len);
229 if (ret > buflen) gu_throw_error(EMSGSIZE) << ret <<
" > " << buflen;
231 offset = __private_unserialize<ST>(buf, buflen, offset, len);
234 if (ret > buflen) gu_throw_error(EMSGSIZE) << ret <<
" > " << buflen;
237 const byte_t*
const ptr(reinterpret_cast<const byte_t*>(buf));
238 copy(ptr + offset, ptr + ret, b.begin());
243 GU_FORCE_INLINE
size_t serialize1(
const Buffer& b,
248 return __private_serialize<uint8_t>(b, buf, buflen, offset);
251 GU_FORCE_INLINE
size_t unserialize1(
const void*
const buf,
256 return __private_unserialize<uint8_t>(buf, buflen, offset, b);
259 GU_FORCE_INLINE
size_t serialize2(
const Buffer& b,
264 return __private_serialize<uint16_t>(b, buf, buflen, offset);
267 GU_FORCE_INLINE
size_t unserialize2(
const void*
const buf,
272 return __private_unserialize<uint16_t>(buf, buflen, offset, b);
275 GU_FORCE_INLINE
size_t serialize4(
const Buffer& b,
280 return __private_serialize<uint32_t>(b, buf, buflen, offset);
283 GU_FORCE_INLINE
size_t unserialize4(
const void*
const buf,
288 return __private_unserialize<uint32_t>(buf, buflen, offset, b);
291 GU_FORCE_INLINE
size_t serialize8(
const Buffer& b,
296 return __private_serialize<uint64_t>(b, buf, buflen, offset);
299 GU_FORCE_INLINE
size_t unserialize8(
const void*
const buf,
304 return __private_unserialize<uint64_t>(buf, buflen, offset, b);
309 #endif // GU_SERIALIZE_HPP