1 #include "../binary/reflector-chronoutilities.h"
2 #include "../binary/reflector.h"
3 #include "../binary/serializable.h"
5 #include <c++utilities/conversion/stringbuilder.h>
6 #include <c++utilities/conversion/stringconversion.h>
7 #include <c++utilities/io/misc.h>
8 #include <c++utilities/tests/testutils.h>
10 using CppUtilities::operator<<;
11 #include <cppunit/TestFixture.h>
12 #include <cppunit/extensions/HelperMacros.h>
21 #include <unordered_map>
25 using namespace CPPUNIT_NS;
26 using namespace CppUtilities;
27 using namespace CppUtilities::Literals;
39 enum class SomeEnumClassBinary : std::uint16_t {
51 map<string, int> someMap;
52 unordered_map<string, bool> someHash;
54 multiset<string> someMultiset;
55 unordered_set<string> someUnorderedSet;
56 unordered_multiset<string> someUnorderedMultiset;
57 SomeEnumBinary someEnum;
58 SomeEnumClassBinary someEnumClass;
65 vector<TestObjectBinary> testObjects;
70 namespace BinaryReflector {
72 template <>
void readCustomType<TestObjectBinary>(BinaryDeserializer &deserializer, TestObjectBinary &customType)
74 deserializer.read(customType.number);
75 deserializer.read(customType.number2);
76 deserializer.read(customType.numbers);
77 deserializer.read(customType.text);
78 deserializer.read(customType.boolean);
79 deserializer.read(customType.someMap);
80 deserializer.read(customType.someHash);
81 deserializer.read(customType.someSet);
82 deserializer.read(customType.someMultiset);
83 deserializer.read(customType.someUnorderedSet);
84 deserializer.read(customType.someUnorderedMultiset);
85 deserializer.read(customType.someEnum);
86 deserializer.read(customType.someEnumClass);
87 deserializer.read(customType.timeSpan);
88 deserializer.read(customType.dateTime);
91 template <>
void writeCustomType<TestObjectBinary>(BinarySerializer &serializer,
const TestObjectBinary &customType)
93 serializer.write(customType.number);
94 serializer.write(customType.number2);
95 serializer.write(customType.numbers);
96 serializer.write(customType.text);
97 serializer.write(customType.boolean);
98 serializer.write(customType.someMap);
99 serializer.write(customType.someHash);
100 serializer.write(customType.someSet);
101 serializer.write(customType.someMultiset);
102 serializer.write(customType.someUnorderedSet);
103 serializer.write(customType.someUnorderedMultiset);
104 serializer.write(customType.someEnum);
105 serializer.write(customType.someEnumClass);
106 serializer.write(customType.timeSpan);
107 serializer.write(customType.dateTime);
110 template <>
void readCustomType<NestingArrayBinary>(BinaryDeserializer &deserializer, NestingArrayBinary &customType)
112 deserializer.read(customType.name);
113 deserializer.read(customType.testObjects);
116 template <>
void writeCustomType<NestingArrayBinary>(BinarySerializer &serializer,
const NestingArrayBinary &customType)
118 serializer.write(customType.name);
119 serializer.write(customType.testObjects);
135 CPPUNIT_TEST(testSerializeSimpleStruct);
136 CPPUNIT_TEST(testDeserializeSimpleStruct);
137 CPPUNIT_TEST(testSerializeNestedStruct);
138 CPPUNIT_TEST(testDeserializeNestedStruct);
139 CPPUNIT_TEST(testSmallSharedPointer);
140 CPPUNIT_TEST(testBigSharedPointer);
141 CPPUNIT_TEST_SUITE_END();
149 void testSerializeSimpleStruct();
150 void testDeserializeSimpleStruct();
151 void testSerializeNestedStruct();
152 void testDeserializeNestedStruct();
153 void assertTestObject(
const TestObjectBinary &deserialized);
154 void testSharedPointer(std::uintptr_t fakePointer);
155 void testSmallSharedPointer();
156 void testBigSharedPointer();
159 vector<unsigned char> m_buffer;
160 TestObjectBinary m_testObj;
161 NestingArrayBinary m_nestedTestObj;
162 vector<unsigned char> m_expectedTestObj;
163 vector<unsigned char> m_expectedNestedTestObj;
173 , m_expectedTestObj({
174 0x00, 0x00, 0x00, 0x05,
175 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x01,
178 0x00, 0x00, 0x00, 0x02,
179 0x00, 0x00, 0x00, 0x03,
180 0x00, 0x00, 0x00, 0x04,
181 0x00, 0x00, 0x00, 0x05,
183 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74,
186 0x83, 0x62, 0x61, 0x72, 0x00, 0x00, 0x00, 0x13,
187 0x83, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x11,
200 0x00, 0x00, 0x00, 0x01,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xAB,
205 , m_expectedNestedTestObj({
206 0x93, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67,
215 m_testObj.number = 5;
216 m_testObj.number2 = 2.5;
217 m_testObj.numbers = { 1, 2, 3, 4, 5 };
218 m_testObj.text =
"some text";
219 m_testObj.boolean =
true;
220 m_testObj.someMap = {
224 m_testObj.someSet = {
"1",
"2",
"3",
"2" };
225 m_testObj.someMultiset = {
"1",
"2",
"3",
"2" };
226 m_testObj.someEnum = SomeEnumItem2;
227 m_testObj.someEnumClass = SomeEnumClassBinary::Item3;
228 m_testObj.timeSpan = TimeSpan(0xABCD);
229 m_testObj.dateTime = DateTime(0xEFAB);
230 m_nestedTestObj.name =
"struct with nesting";
231 m_expectedNestedTestObj.reserve(m_expectedNestedTestObj.size() + 2 * m_expectedTestObj.size());
232 m_expectedNestedTestObj.insert(m_expectedNestedTestObj.end(), m_expectedTestObj.cbegin(), m_expectedTestObj.cend());
233 m_expectedNestedTestObj.insert(m_expectedNestedTestObj.end(), m_expectedTestObj.cbegin(), m_expectedTestObj.cend());
234 m_nestedTestObj.testObjects.insert(m_nestedTestObj.testObjects.end(), 2, m_testObj);
243 stringstream stream(ios_base::out | ios_base::binary);
244 stream.exceptions(ios_base::failbit | ios_base::badbit);
245 m_buffer.resize(m_expectedTestObj.size());
246 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_buffer.data()), static_cast<streamsize>(m_buffer.size()));
247 m_testObj.toBinary(stream);
249 CPPUNIT_ASSERT_EQUAL(m_expectedTestObj, m_buffer);
254 stringstream stream(ios_base::in | ios_base::binary);
255 stream.exceptions(ios_base::failbit | ios_base::badbit);
256 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_expectedTestObj.data()), static_cast<streamsize>(m_expectedTestObj.size()));
257 const auto deserialized(TestObjectBinary::fromBinary(stream));
263 stringstream stream(ios_base::out | ios_base::binary);
264 stream.exceptions(ios_base::failbit | ios_base::badbit);
265 m_buffer.resize(m_expectedNestedTestObj.size());
266 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_buffer.data()), static_cast<streamsize>(m_buffer.size()));
267 m_nestedTestObj.toBinary(stream);
269 CPPUNIT_ASSERT_EQUAL(m_expectedNestedTestObj, m_buffer);
274 stringstream stream(ios_base::in | ios_base::binary);
275 stream.exceptions(ios_base::failbit | ios_base::badbit);
276 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_expectedNestedTestObj.data()), static_cast<streamsize>(m_expectedNestedTestObj.size()));
278 const auto deserialized(NestingArrayBinary::fromBinary(stream));
279 CPPUNIT_ASSERT_EQUAL(m_nestedTestObj.name, deserialized.name);
280 for (
const auto &testObj : deserialized.testObjects) {
287 CPPUNIT_ASSERT_EQUAL(m_testObj.number, deserialized.number);
288 CPPUNIT_ASSERT_EQUAL(m_testObj.number2, deserialized.number2);
289 CPPUNIT_ASSERT_EQUAL(m_testObj.numbers, deserialized.numbers);
290 CPPUNIT_ASSERT_EQUAL(m_testObj.text, deserialized.text);
291 CPPUNIT_ASSERT_EQUAL(m_testObj.boolean, deserialized.boolean);
292 CPPUNIT_ASSERT_EQUAL(m_testObj.someMap, deserialized.someMap);
293 CPPUNIT_ASSERT_EQUAL(m_testObj.someHash, deserialized.someHash);
294 CPPUNIT_ASSERT_EQUAL(m_testObj.someSet, deserialized.someSet);
295 CPPUNIT_ASSERT_EQUAL(m_testObj.someMultiset, deserialized.someMultiset);
296 CPPUNIT_ASSERT_EQUAL(m_testObj.someUnorderedSet, deserialized.someUnorderedSet);
297 CPPUNIT_ASSERT_EQUAL(m_testObj.someUnorderedMultiset, deserialized.someUnorderedMultiset);
303 shared_ptr<int> sharedPointer(reinterpret_cast<int *>(fakePointer), [](
int *) {});
306 stringstream stream(ios_base::in | ios_base::out | ios_base::binary);
307 stream.exceptions(ios_base::failbit | ios_base::badbit);
311 serializer.
m_pointer[fakePointer] =
true;
312 serializer.
write(sharedPointer);
316 shared_ptr<int> readPtr;
317 deserializer.
m_pointer[fakePointer] =
"foo";
318 CPPUNIT_ASSERT_THROW(deserializer.
read(readPtr), CppUtilities::ConversionException);
319 CPPUNIT_ASSERT(readPtr ==
nullptr);
323 deserializer.
m_pointer[fakePointer] = make_shared<int>(42);
324 deserializer.
read(readPtr);
325 CPPUNIT_ASSERT(readPtr !=
nullptr);
326 CPPUNIT_ASSERT_EQUAL(42, *readPtr);