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