Pioneer
Loading...
Searching...
No Matches
Serializer.h
Go to the documentation of this file.
1// Copyright © 2008-2024 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef _SERIALIZE_H
5#define _SERIALIZE_H
6
7#include "Aabb.h"
8#include "ByteRange.h"
9#include "Color.h"
10#include "Quaternion.h"
11#include "vector3.h"
12#include <cstring>
13#include <stdexcept>
14#include <string>
15
16#if (__GNUC__ && (__BYTE_ORDER_ == __ORDER_BIG_ENDIAN__)) || (__clang__ && __BIG_ENDIAN__)
17#error Serializer.h is incompatible with big-endian architectures!
18#endif
19
20// Note: this serializer implementation is for use on little-endian runtimes
21// only. It depends on floating point types having the same IEEE-754 semantics
22// on both ends, and allows you to write unsafe code if care is not taken.
23// It is intended only for the efficient (de)serialization of model binary data;
24// where possible, prefer serializing state information via JSON instead.
25namespace Serializer {
26 static_assert((sizeof(Uint32) == 4 && alignof(Uint32) <= 4), "Int32 is sized differently on this platform and will not serialize properly.");
27 static_assert((sizeof(Uint64) == 8 && alignof(Uint64) <= 8), "Int64 is sized differently on this platform and will not serialize properly.");
28 static_assert((sizeof(Color) == 4 && alignof(Color) <= 1), "Color is padded differently on this platform and will not serialize properly.");
29 static_assert((sizeof(vector2f) == 8 && alignof(vector2f) <= 4), "Vector2f is padded differently on this platform and will not serialize properly.");
30 static_assert((sizeof(vector2d) == 16 && alignof(vector2d) <= 8), "Vector2d is padded differently on this platform and will not serialize properly.");
31 static_assert((sizeof(vector3f) == 12 && alignof(vector3f) <= 4), "Vector3f is padded differently on this platform and will not serialize properly.");
32 static_assert((sizeof(vector3d) == 24 && alignof(vector3d) <= 8), "Vector3d is padded differently on this platform and will not serialize properly.");
33 static_assert((sizeof(Quaternionf) == 16 && alignof(Quaternionf) <= 4), "Quaternionf is padded differently on this platform and will not serialize properly.");
34 static_assert((sizeof(Aabb) == 56 && alignof(Aabb) <= 8), "Aabb is padded differently on this platform and will not serialize properly.");
35
36 class Writer {
37 public:
38 Writer() {}
39 const std::string &GetData() { return m_str; }
40
41 template <typename T>
42 void writeObject(const T &obj)
43 {
44 m_str.append(reinterpret_cast<const char *>(&obj), sizeof(T));
45 }
46
47 void writeObject(const std::string &obj)
48 {
49 writeObject<Uint32>(obj.size());
50 m_str.append(obj.c_str(), obj.size());
51 }
52
53 void writeObject(const char *s)
54 {
55 if (!s) { // don't fail on invalid string, just write a zero-length blob.
56 *this << 0U;
57 return;
58 }
59
60 Uint32 len = strlen(s);
61 *this << len;
62 m_str.append(s, len);
63 }
64
65 void writeObject(const vector2f &vec) { *this << vec.x << vec.y; }
66 void writeObject(const vector2d &vec) { *this << vec.x << vec.y; }
67 void writeObject(const vector3f &vec) { *this << vec.x << vec.y << vec.z; }
68 void writeObject(const vector3d &vec) { *this << vec.x << vec.y << vec.z; }
69 void writeObject(const Color &col) { *this << col.r << col.g << col.b << col.a; }
70 void writeObject(const Quaternionf &quat) { *this << quat.w << quat.x << quat.y << quat.z; }
71 void writeObject(const Quaterniond &quat) { *this << quat.w << quat.x << quat.y << quat.z; }
72 void writeObject(const Aabb &aabb) { *this << aabb.min << aabb.max << aabb.radius; }
73
74 template <typename T>
75 Writer &operator<<(const T &obj)
76 {
77 writeObject(obj);
78 return *this;
79 }
80
81 void Blob(ByteRange range)
82 {
83 assert(range.Size() < SDL_MAX_UINT32);
84 Int32(range.Size());
85 if (range.Size()) {
86 m_str.append(range.begin, range.Size());
87 }
88 }
89 void Byte(Uint8 x) { *this << x; }
90 void Bool(bool x) { *this << x; }
91 void Int16(Uint16 x) { *this << x; }
92 void Int32(Uint32 x) { *this << x; }
93 void Int64(Uint64 x) { *this << x; }
94 void Float(float f) { *this << f; }
95 void Double(double f) { *this << f; }
96 void String(const char *s) { *this << s; }
97 void String(const std::string &s) { *this << s; }
98
99 void Vector2f(vector2f vec) { *this << vec; }
100 void Vector2d(vector2d vec) { *this << vec; }
101 void Vector3f(vector3f vec) { *this << vec; }
102 void Vector3d(vector3d vec) { *this << vec; }
103 void WrQuaternionf(const Quaternionf &q) { *this << q; }
104 void Color4UB(const Color &c) { *this << c; }
105 void WrSection(const std::string &section_label, const std::string &section_data) { *this << section_label << section_data; }
106
107 private:
108 std::string m_str;
109 };
110
111 class Reader {
112 template <typename T>
113 T obj()
114 {
115 T _ob;
116 readObject(_ob);
117 return _ob;
118 }
119
120 public:
122 m_at(nullptr),
123 m_streamVersion(-1)
124 {
125 }
126
127 explicit Reader(const ByteRange &data) :
128 m_data(data),
129 m_at(data.begin)
130 {
131 }
132
133 bool AtEnd() { return m_at != m_data.end; }
134
135 bool Check(std::size_t needed_size)
136 {
137 return m_data.end >= m_at + needed_size;
138 }
139
140 void Seek(int pos)
141 {
142 assert(pos >= 0 && std::size_t(pos) < m_data.Size());
143 m_at = m_data.begin + pos;
144 }
145
146 std::size_t Pos() { return std::size_t(m_at - m_data.begin); }
147
148 template <typename T>
149 void readObject(T &out)
150 {
151#ifdef DEBUG
152 if (!Check(sizeof(T)))
153 throw std::out_of_range("Serializer::Reader encountered truncated stream.");
154#endif
155
156 std::memcpy(&out, m_at, sizeof(T)); // use memcpy to handle unaligned reads
157 m_at += sizeof(T);
158 }
159
160 void readObject(std::string &out)
161 {
162 ByteRange range = Blob();
163 out = std::string(range.begin, range.Size());
164 if (!out.empty() && *(out.end() - 1) == '\0') // HACK, old SGM files have trailing '\0' de-serialised sometimes
165 out.pop_back();
166 }
167
168 void readObject(vector2f &vec) { *this >> vec.x >> vec.y; }
169 void readObject(vector2d &vec) { *this >> vec.x >> vec.y; }
170 void readObject(vector3f &vec) { *this >> vec.x >> vec.y >> vec.z; }
171 void readObject(vector3d &vec) { *this >> vec.x >> vec.y >> vec.z; }
172 void readObject(Color &col) { *this >> col.r >> col.g >> col.b >> col.a; }
173 void readObject(Quaternionf &quat) { *this >> quat.w >> quat.x >> quat.y >> quat.z; }
174 void readObject(Quaterniond &quat) { *this >> quat.w >> quat.x >> quat.y >> quat.z; }
175 void readObject(Aabb &aabb) { *this >> aabb.min >> aabb.max >> aabb.radius; }
176
177 template <typename T>
179 {
180 readObject(out);
181 return *this;
182 }
183
185 {
186 auto len = Int32();
187 if (len == 0) return ByteRange();
188 if (len > (m_data.end - m_at))
189 throw std::out_of_range("Serializer::Reader encountered truncated stream.");
190
191 auto range = ByteRange(m_at, m_at + len);
192 m_at += len;
193 return range;
194 }
195
196 // Prefer using Reader::operator>> instead; these functions involve creating an unnessesary temporary variable.
197 bool Bool() { return obj<bool>(); }
198 Uint8 Byte() { return obj<Uint8>(); }
199 Uint16 Int16() { return obj<Uint16>(); }
200 Uint32 Int32() { return obj<Uint32>(); }
201 Uint64 Int64() { return obj<Uint64>(); }
202 float Float() { return obj<float>(); }
203 double Double() { return obj<double>(); }
204
205 std::string String() { return obj<std::string>(); }
206
207 Color Color4UB() { return obj<Color>(); }
208 vector2f Vector2f() { return obj<vector2f>(); }
209 vector2d Vector2d() { return obj<vector2d>(); }
210 vector3f Vector3f() { return obj<vector3f>(); }
211 vector3d Vector3d() { return obj<vector3d>(); }
212
213 Quaternionf RdQuaternionf() { return obj<Quaternionf>(); }
214
215 Reader RdSection(const std::string &section_label_expected);
216
217 int StreamVersion() const { return m_streamVersion; }
218 void SetStreamVersion(int x) { m_streamVersion = x; }
219
220 private:
221 ByteRange m_data;
222 const char *m_at;
223 int m_streamVersion;
224 };
225
226} // namespace Serializer
227
228#endif /* _SERIALIZE_H */
Color4ub Color
Definition: Color.h:212
Quaternion< float > Quaternionf
Definition: Quaternion.h:277
T y
Definition: Quaternion.h:17
T x
Definition: Quaternion.h:17
T w
Definition: Quaternion.h:17
T z
Definition: Quaternion.h:17
Definition: Serializer.h:111
bool AtEnd()
Definition: Serializer.h:133
void readObject(std::string &out)
Definition: Serializer.h:160
void readObject(vector2f &vec)
Definition: Serializer.h:168
Reader RdSection(const std::string &section_label_expected)
Definition: Serializer.cpp:9
Uint64 Int64()
Definition: Serializer.h:201
Reader & operator>>(T &out)
Definition: Serializer.h:178
std::size_t Pos()
Definition: Serializer.h:146
Uint8 Byte()
Definition: Serializer.h:198
Quaternionf RdQuaternionf()
Definition: Serializer.h:213
std::string String()
Definition: Serializer.h:205
void readObject(Quaternionf &quat)
Definition: Serializer.h:173
void Seek(int pos)
Definition: Serializer.h:140
void readObject(vector3f &vec)
Definition: Serializer.h:170
Reader(const ByteRange &data)
Definition: Serializer.h:127
void readObject(Aabb &aabb)
Definition: Serializer.h:175
void readObject(Color &col)
Definition: Serializer.h:172
void readObject(vector2d &vec)
Definition: Serializer.h:169
void readObject(vector3d &vec)
Definition: Serializer.h:171
vector3f Vector3f()
Definition: Serializer.h:210
bool Bool()
Definition: Serializer.h:197
Reader()
Definition: Serializer.h:121
vector2d Vector2d()
Definition: Serializer.h:209
Uint32 Int32()
Definition: Serializer.h:200
vector2f Vector2f()
Definition: Serializer.h:208
vector3d Vector3d()
Definition: Serializer.h:211
bool Check(std::size_t needed_size)
Definition: Serializer.h:135
void SetStreamVersion(int x)
Definition: Serializer.h:218
float Float()
Definition: Serializer.h:202
ByteRange Blob()
Definition: Serializer.h:184
void readObject(Quaterniond &quat)
Definition: Serializer.h:174
Color Color4UB()
Definition: Serializer.h:207
int StreamVersion() const
Definition: Serializer.h:217
void readObject(T &out)
Definition: Serializer.h:149
Uint16 Int16()
Definition: Serializer.h:199
double Double()
Definition: Serializer.h:203
Definition: Serializer.h:36
void writeObject(const Color &col)
Definition: Serializer.h:69
const std::string & GetData()
Definition: Serializer.h:39
void writeObject(const vector3f &vec)
Definition: Serializer.h:67
void Double(double f)
Definition: Serializer.h:95
void writeObject(const vector2d &vec)
Definition: Serializer.h:66
void Byte(Uint8 x)
Definition: Serializer.h:89
void Bool(bool x)
Definition: Serializer.h:90
void WrSection(const std::string &section_label, const std::string &section_data)
Definition: Serializer.h:105
void Color4UB(const Color &c)
Definition: Serializer.h:104
void Vector3d(vector3d vec)
Definition: Serializer.h:102
void Blob(ByteRange range)
Definition: Serializer.h:81
Writer()
Definition: Serializer.h:38
void Vector2d(vector2d vec)
Definition: Serializer.h:100
void Vector2f(vector2f vec)
Definition: Serializer.h:99
void String(const char *s)
Definition: Serializer.h:96
void Int16(Uint16 x)
Definition: Serializer.h:91
void writeObject(const vector3d &vec)
Definition: Serializer.h:68
void Int32(Uint32 x)
Definition: Serializer.h:92
void writeObject(const vector2f &vec)
Definition: Serializer.h:65
void Int64(Uint64 x)
Definition: Serializer.h:93
void writeObject(const T &obj)
Definition: Serializer.h:42
void Vector3f(vector3f vec)
Definition: Serializer.h:101
void writeObject(const char *s)
Definition: Serializer.h:53
void writeObject(const std::string &obj)
Definition: Serializer.h:47
void Float(float f)
Definition: Serializer.h:94
void writeObject(const Aabb &aabb)
Definition: Serializer.h:72
void String(const std::string &s)
Definition: Serializer.h:97
Writer & operator<<(const T &obj)
Definition: Serializer.h:75
void WrQuaternionf(const Quaternionf &q)
Definition: Serializer.h:103
void writeObject(const Quaterniond &quat)
Definition: Serializer.h:71
void writeObject(const Quaternionf &quat)
Definition: Serializer.h:70
T y
Definition: vector2.h:26
T x
Definition: vector2.h:26
T y
Definition: vector3.h:20
T x
Definition: vector3.h:20
T z
Definition: vector3.h:20
Definition: GeomTree.h:12
Definition: Aabb.h:11
vector3d max
Definition: Aabb.h:12
vector3d min
Definition: Aabb.h:12
double radius
Definition: Aabb.h:13
Definition: ByteRange.h:12
size_t Size() const
Definition: ByteRange.h:34
const char * end
Definition: ByteRange.h:31
const char * begin
Definition: ByteRange.h:30
Definition: Color.h:66
Uint8 a
Definition: Color.h:68
Uint8 b
Definition: Color.h:68
Uint8 g
Definition: Color.h:68
Uint8 r
Definition: Color.h:68
vector2< float > vector2f
Definition: vector2.h:133
vector2< double > vector2d
Definition: vector2.h:134
vector3< float > vector3f
Definition: vector3.h:328
vector3< double > vector3d
Definition: vector3.h:329