Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
bytestream.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
20#include <sstream>
21#include <string>
22#include <vector>
23
24namespace shambase {
25
26 template<class T>
27 inline void stream_write(std::basic_stringstream<byte> &stream, T &obj) {
28 stream.write(reinterpret_cast<byte const *>(&obj), sizeof(obj));
29 }
30
31 template<class T>
32 inline void stream_read(std::basic_stringstream<byte> &stream, T &obj) {
33 stream.read(reinterpret_cast<byte *>(&obj), sizeof(obj));
34 }
35
36 inline void stream_write_string(std::basic_stringstream<byte> &stream, std::string &s) {
37 u64 strlen = s.size();
38 stream_write(stream, strlen);
39 stream.write(reinterpret_cast<byte const *>(s.data()), strlen * sizeof(char));
40 }
41
42 inline void stream_read_string(std::basic_stringstream<byte> &stream, std::string &s) {
43 u64 strlen;
44 stream_read<u64>(stream, strlen);
45 s.resize(strlen);
46 stream.read(reinterpret_cast<byte *>(s.data()), strlen * sizeof(char));
47 }
48
49 namespace details {
50 template<typename T>
51 using serialize_t = decltype(std::declval<T>().serialize(
52 std::declval<std::basic_stringstream<byte> &>()));
53
54 template<typename Container, typename = std::void_t<>>
55 struct has_serialize : std::false_type {};
56
57 template<typename Container>
58 struct has_serialize<Container, std::void_t<serialize_t<Container>>> : std::true_type {};
59
60 template<typename Container>
61 inline constexpr bool has_serialize_v = has_serialize<Container>::value;
62
63 template<typename T>
64 using deserialize_t
65 = decltype(T::deserialize(std::declval<std::basic_stringstream<byte> &>()));
66
67 template<typename Container, typename = std::void_t<>>
68 struct has_deserialize : std::false_type {};
69
70 template<typename Container>
71 struct has_deserialize<Container, std::void_t<deserialize_t<Container>>> : std::true_type {
72 };
73
74 template<typename Container>
75 inline constexpr bool has_deserialize_v = has_deserialize<Container>::value;
76
77 enum VALIDATION_FLAGS {
78 VECTOR = 0x124,
79 };
80
81 class bytestreamException : public std::exception {
82 public:
83 explicit bytestreamException(const char *message) : msg_(message) {}
84
85 explicit bytestreamException(const std::string &message) : msg_(message) {}
86
87 virtual ~bytestreamException() noexcept {}
88
89 virtual const char *what() const noexcept { return msg_.c_str(); }
90
91 protected:
92 std::string msg_;
93 };
94 } // namespace details
95
103 template<class T>
104 inline void stream_write_vector(std::basic_stringstream<byte> &stream, std::vector<T> &vec) {
105
106 static_assert(
107 details::has_serialize_v<T>, "the template class must have serialize implemented");
108
109 u32 flag = details::VALIDATION_FLAGS::VECTOR;
110 stream_write(stream, flag);
111
112 u64 len = vec.size();
113 stream_write(stream, len);
114 for (T &v : vec) {
115 v.serialize(stream);
116 }
117 }
118
127 template<class T>
128 inline void stream_read_vector(std::basic_stringstream<byte> &stream, std::vector<T> &vec) {
129 static_assert(
130 details::has_serialize_v<T>, "the template class must have deserialize implemented");
131
132 u32 flag;
133 stream_read(stream, flag);
134 if (flag != details::VALIDATION_FLAGS::VECTOR) {
135 throw details::bytestreamException("the validation flags don't match");
136 }
137
138 u64 len;
139 stream_read(stream, len);
140 for (u64 i = 0; i < len; i++) {
141 vec.push_back(T::deserialize(stream));
142 }
143 }
144
145 template<class T>
146 inline void stream_write_vector_trivial(
147 std::basic_stringstream<byte> &stream, std::vector<T> &vec) {
148
149 u32 flag = details::VALIDATION_FLAGS::VECTOR;
150 stream_write(stream, flag);
151
152 u64 len = vec.size();
153 stream_write(stream, len);
154
155 stream.write(reinterpret_cast<byte const *>(vec.data()), len * sizeof(T));
156 }
157
166 template<class T>
168 std::basic_stringstream<byte> &stream, std::vector<T> &vec) {
169
170 u32 flag;
171 stream_read(stream, flag);
172 if (flag != details::VALIDATION_FLAGS::VECTOR) {
173 throw details::bytestreamException("the validation flags don't match");
174 }
175
176 u64 len;
177 stream_read(stream, len);
178 vec.resize(len);
179
180 stream.read(reinterpret_cast<byte *>(vec.data()), len * sizeof(T));
181 }
182
183} // namespace shambase
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
Namespace for internal details of the logs module.
namespace for basic c++ utilities
void stream_read_vector(std::basic_stringstream< byte > &stream, std::vector< T > &vec)
read a vector from the bytestream Note : this appends read objects to the vector without resetting it
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
void stream_read_vector_trivial(std::basic_stringstream< byte > &stream, std::vector< T > &vec)
read a vector from the bytestream Note : this appends read objects to the vector without resetting it
void stream_write_vector(std::basic_stringstream< byte > &stream, std::vector< T > &vec)
write the vector into the bytestream
STL namespace.