ScummVM API documentation
serializer.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef COMMON_SERIALIZER_H
23 #define COMMON_SERIALIZER_H
24 
25 #include "common/stream.h"
26 #include "common/str.h"
27 
28 namespace Common {
29 
39 #define VER(x) Common::Serializer::Version(x)
40 
41 #define SYNC_AS(SUFFIX,TYPE,SIZE) \
42  template<typename T> \
43  void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \
44  if (_version < minVersion || _version > maxVersion) \
45  return; \
46  if (_loadStream) \
47  val = static_cast<T>(_loadStream->read ## SUFFIX()); \
48  else { \
49  TYPE tmp = val; \
50  _saveStream->write ## SUFFIX(tmp); \
51  } \
52  _bytesSynced += SIZE; \
53  }
54 
55 #define SYNC_PRIMITIVE(suffix) \
56  template <typename T> \
57  static inline void suffix(Serializer &s, T &value) { \
58  s.syncAs##suffix(value); \
59  }
60 
79 class Serializer {
80 public:
81  typedef uint32 Version;
82  static const Version kLastVersion = 0xFFFFFFFF;
83 
84  SYNC_PRIMITIVE(Uint32LE)
85  SYNC_PRIMITIVE(Uint32BE)
86  SYNC_PRIMITIVE(Sint32LE)
87  SYNC_PRIMITIVE(Sint32BE)
88  SYNC_PRIMITIVE(FloatLE)
89  SYNC_PRIMITIVE(FloatBE)
90  SYNC_PRIMITIVE(DoubleLE)
91  SYNC_PRIMITIVE(DoubleBE)
92  SYNC_PRIMITIVE(Uint16LE)
93  SYNC_PRIMITIVE(Uint16BE)
94  SYNC_PRIMITIVE(Sint16LE)
95  SYNC_PRIMITIVE(Sint16BE)
96  SYNC_PRIMITIVE(Byte)
97  SYNC_PRIMITIVE(SByte)
98 
99 protected:
100  SeekableReadStream *_loadStream;
101  WriteStream *_saveStream;
102 
103  uint _bytesSynced;
104 
105  Version _version;
106 
107 public:
109  : _loadStream(in), _saveStream(out), _bytesSynced(0), _version(0) {
110  assert(in || out);
111  }
112  virtual ~Serializer() {}
113 
114  inline bool isSaving() { return (_saveStream != 0); }
115  inline bool isLoading() { return (_loadStream != 0); }
116 
117  SYNC_AS(Byte, byte, 1)
118  SYNC_AS(SByte, int8, 1)
119 
120  SYNC_AS(Uint16LE, uint16, 2)
121  SYNC_AS(Uint16BE, uint16, 2)
122  SYNC_AS(Sint16LE, int16, 2)
123  SYNC_AS(Sint16BE, int16, 2)
124 
125  SYNC_AS(Uint32LE, uint32, 4)
126  SYNC_AS(Uint32BE, uint32, 4)
127  SYNC_AS(Sint32LE, int32, 4)
128  SYNC_AS(Sint32BE, int32, 4)
129  SYNC_AS(FloatLE, float, 4)
130  SYNC_AS(FloatBE, float, 4)
131 
132  SYNC_AS(DoubleLE, double, 8)
133  SYNC_AS(DoubleBE, double, 8)
134 
135 
140  bool err() const {
141  if (_saveStream)
142  return _saveStream->err();
143  else
144  return _loadStream->err();
145  }
146 
150  void clearErr() {
151  if (_saveStream)
152  _saveStream->clearErr();
153  else
154  _loadStream->clearErr();
155  }
156 
162  bool syncVersion(Version currentVersion) {
163  _version = currentVersion;
164  syncAsUint32LE(_version);
165  return _version <= currentVersion;
166  }
167 
172  Version getVersion() const { return _version; }
173 
177  void setVersion(Version version) { _version = version; }
178 
182  uint bytesSynced() const { return _bytesSynced; }
183 
188  void skip(uint32 size, Version minVersion = 0, Version maxVersion = kLastVersion) {
189  if (_version < minVersion || _version > maxVersion)
190  return; // Ignore anything which is not supposed to be present in this save game version
191 
192  _bytesSynced += size;
193  if (isLoading())
194  _loadStream->skip(size);
195  else {
196  while (size--)
197  _saveStream->writeByte(0);
198  }
199  }
200 
204  void syncBytes(byte *buf, uint32 size, Version minVersion = 0, Version maxVersion = kLastVersion) {
205  if (_version < minVersion || _version > maxVersion)
206  return; // Ignore anything which is not supposed to be present in this save game version
207 
208  if (isLoading())
209  _loadStream->read(buf, size);
210  else
211  _saveStream->write(buf, size);
212  _bytesSynced += size;
213  }
214 
227  bool matchBytes(const char *magic, byte size, Version minVersion = 0, Version maxVersion = kLastVersion) {
228  if (_version < minVersion || _version > maxVersion)
229  return true; // Ignore anything which is not supposed to be present in this save game version
230 
231  bool match;
232  if (isSaving()) {
233  _saveStream->write(magic, size);
234  match = true;
235  } else {
236  char buf[256];
237  _loadStream->read(buf, size);
238  match = (0 == memcmp(buf, magic, size));
239  }
240  _bytesSynced += size;
241  return match;
242  }
243 
248  void syncString(String &str, Version minVersion = 0, Version maxVersion = kLastVersion) {
249  if (_version < minVersion || _version > maxVersion)
250  return; // Ignore anything which is not supposed to be present in this save game version
251 
252  if (isLoading()) {
253  char c;
254  str.clear();
255  while ((c = _loadStream->readByte())) {
256  str += c;
257  _bytesSynced++;
258  }
259  _bytesSynced++;
260  } else {
261  _saveStream->writeString(str);
262  _saveStream->writeByte(0);
263  _bytesSynced += str.size() + 1;
264  }
265  }
266 
270  void syncString32(U32String &str, Version minVersion = 0, Version maxVersion = kLastVersion) {
271  if (_version < minVersion || _version > maxVersion)
272  return; // Ignore anything which is not supposed to be present in this save game version
273 
274  uint32 len = str.size();
275 
276  syncAsUint32LE(len);
277 
278  if (isLoading()) {
279  U32String::value_type *sl = new U32String::value_type[len];
280  for (uint i = 0; i < len; i++)
281  syncAsUint32LE(sl[i]);
282  str = U32String(sl, len);
283  delete[] sl;
284  } else {
285  for (uint i = 0; i < len; i++)
286  _saveStream->writeUint32LE(str[i]);
287  _bytesSynced += 4 * len;
288  }
289  }
290 
291  template <typename T>
292  void syncArray(T *arr, size_t entries, void (*serializer)(Serializer &, T &), Version minVersion = 0, Version maxVersion = kLastVersion) {
293  if (_version < minVersion || _version > maxVersion)
294  return;
295 
296  for (size_t i = 0; i < entries; ++i) {
297  serializer(*this, arr[i]);
298  }
299  }
300 };
301 
302 #undef SYNC_PRIMITIVE
303 #undef SYNC_AS
304 
305 
306 // Mixin class / interface
307 // TODO: Maybe rename this to Syncable ?
309 public:
310  virtual ~Serializable() {}
311 
312  // Maybe rename this method to "syncWithSerializer" or "syncUsingSerializer" ?
313  virtual void saveLoadWithSerializer(Serializer &ser) = 0;
314 };
315 
318 } // End of namespace Common
319 
320 #endif
void syncBytes(byte *buf, uint32 size, Version minVersion=0, Version maxVersion=kLastVersion)
Definition: serializer.h:204
Definition: str.h:59
virtual bool err() const
Definition: stream.h:61
void writeUint32LE(uint32 value)
Definition: stream.h:159
Definition: stream.h:77
virtual void clearErr()
Definition: stream.h:71
uint bytesSynced() const
Definition: serializer.h:182
void clearErr()
Definition: serializer.h:150
Definition: stream.h:745
bool syncVersion(Version currentVersion)
Definition: serializer.h:162
Definition: serializer.h:79
byte readByte()
Definition: stream.h:434
Definition: ustr.h:57
void setVersion(Version version)
Definition: serializer.h:177
void syncString(String &str, Version minVersion=0, Version maxVersion=kLastVersion)
Definition: serializer.h:248
Definition: algorithm.h:29
bool err() const
Definition: serializer.h:140
Definition: serializer.h:308
void syncString32(U32String &str, Version minVersion=0, Version maxVersion=kLastVersion)
Definition: serializer.h:270
Version getVersion() const
Definition: serializer.h:172
bool matchBytes(const char *magic, byte size, Version minVersion=0, Version maxVersion=kLastVersion)
Definition: serializer.h:227
void skip(uint32 size, Version minVersion=0, Version maxVersion=kLastVersion)
Definition: serializer.h:188
virtual uint32 write(const void *dataPtr, uint32 dataSize)=0
void writeString(const String &str)
virtual uint32 read(void *dataPtr, uint32 dataSize)=0
virtual bool skip(uint32 offset)
Definition: stream.h:793
void writeByte(byte value)
Definition: stream.h:140