aboutsummaryrefslogtreecommitdiff
path: root/test/common
diff options
context:
space:
mode:
authorMax Horn2009-05-19 11:23:13 +0000
committerMax Horn2009-05-19 11:23:13 +0000
commit42cd21840055d97315eac8b78f110010e5270d2d (patch)
treefafcf0eb8f3edd126c84f710382e43c42d746f5d /test/common
parent2b32ba7cb375dd80a119f56f661811971c671ca3 (diff)
downloadscummvm-rg350-42cd21840055d97315eac8b78f110010e5270d2d.tar.gz
scummvm-rg350-42cd21840055d97315eac8b78f110010e5270d2d.tar.bz2
scummvm-rg350-42cd21840055d97315eac8b78f110010e5270d2d.zip
Improved Common::Serializer in several ways:
* Added support versioned serialization * Added a convenience API for handling 'magic IDs' transparently * Exposed the err()/clearErr() methods of the underlying streams * Added a basic unit test for versioned loading (more should be added, in particular for saving) * Removed the syncString(char *, uint16) alias for syncBytes(byte *buf, uint32 size) svn-id: r40723
Diffstat (limited to 'test/common')
-rw-r--r--test/common/serializer.h111
1 files changed, 111 insertions, 0 deletions
diff --git a/test/common/serializer.h b/test/common/serializer.h
new file mode 100644
index 0000000000..7f79d88de0
--- /dev/null
+++ b/test/common/serializer.h
@@ -0,0 +1,111 @@
+#include <cxxtest/TestSuite.h>
+
+#include "common/serializer.h"
+#include "common/stream.h"
+
+class SerializerTestSuite : public CxxTest::TestSuite {
+ Common::SeekableReadStream *_inStreamV1;
+ Common::SeekableReadStream *_inStreamV2;
+public:
+ void setUp() {
+ // Our pseudo data format is as follows:
+ // * magic id - string "MAGI"
+ // * Version - uint32, LE
+ // * uint32, LE (available in v2 onward)
+ // * uint16, BE (available in v1 onward)
+ // * sint16, LE (available only in v1)
+ // * byte (always available)
+ static const byte contents_v1[] = {
+ 'M', 'A', 'G', 'I', // magic id
+ 0x01, 0x00, 0x00, 0x00, // Version
+ 0x06, 0x07, // uint16, BE (available in v1 onward)
+ 0xfe, 0xff, // sint16, LE (available only in v1)
+ 0x0a // byte (always available)
+ };
+ static const byte contents_v2[] = {
+ 'M', 'A', 'G', 'I', // magic id
+ 0x02, 0x00, 0x00, 0x00, // Version
+ 0x02, 0x03, 0x04, 0x05, // uint32, LE (available in v2 onward)
+ 0x06, 0x07, // uint16, BE (available in v1 onward)
+ 0x0a // byte (always available)
+ };
+
+ _inStreamV1 = new Common::MemoryReadStream(contents_v1, sizeof(contents_v1));
+ _inStreamV2 = new Common::MemoryReadStream(contents_v2, sizeof(contents_v2));
+ }
+
+ void tearDown() {
+ delete _inStreamV1;
+ delete _inStreamV2;
+ }
+
+ // A method which reads a v1 file
+ void readVersioned_v1(Common::SeekableReadStream *stream, int version) {
+ Common::Serializer ser(stream, 0);
+
+ TS_ASSERT(ser.syncMagic("MAGI", 4));
+
+ TS_ASSERT(ser.syncVersion(1));
+ TS_ASSERT_EQUALS(ser.getVersion(), version);
+
+ uint32 tmp;
+
+ ser.syncAsUint16BE(tmp, Common::Serializer::Version(1));
+ TS_ASSERT_EQUALS(tmp, 0x0607);
+
+ ser.syncAsSint16LE(tmp, Common::Serializer::Version(1));
+ TS_ASSERT_EQUALS(tmp, -2);
+
+ ser.syncAsByte(tmp);
+ TS_ASSERT_EQUALS(tmp, 0x0a);
+ }
+
+ // A method which reads a v2 file
+ void readVersioned_v2(Common::SeekableReadStream *stream, int version) {
+ Common::Serializer ser(stream, 0);
+
+ TS_ASSERT(ser.syncMagic("MAGI", 4));
+
+ TS_ASSERT(ser.syncVersion(2));
+ TS_ASSERT_EQUALS(ser.getVersion(), version);
+
+ uint32 tmp;
+
+ // Read a value only available starting with v2.
+ // Thus if we load an old save, it must be
+ // manually set. To simplify that, no sync method should
+ // modify the value passed to it if nothing was read!
+ tmp = 0x12345678;
+ ser.syncAsUint32LE(tmp, Common::Serializer::Version(2));
+ if (ser.getVersion() < 2) {
+ TS_ASSERT_EQUALS(tmp, 0x12345678);
+ } else {
+ TS_ASSERT_EQUALS(tmp, 0x05040302);
+ }
+
+ ser.syncAsUint16BE(tmp, Common::Serializer::Version(1));
+ TS_ASSERT_EQUALS(tmp, 0x0607);
+
+ // Skip over obsolete data
+ ser.skip(2, Common::Serializer::Version(1), Common::Serializer::Version(1));
+
+ ser.syncAsByte(tmp);
+ TS_ASSERT_EQUALS(tmp, 0x0a);
+ }
+
+ void test_read_v1_as_v1() {
+ readVersioned_v1(_inStreamV1, 1);
+ }
+
+ // There is no test_read_v2_as_v1() because a v1 parser cannot possibly
+ // read v2 data correctly. It should instead error out if it
+ // detects a version newer than its current version.
+
+ void test_read_v2_as_v1() {
+ readVersioned_v2(_inStreamV1, 1);
+ }
+
+ void test_read_v2_as_v2() {
+ readVersioned_v2(_inStreamV2, 2);
+ }
+};