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 TestUtilities::operator<<;
11 #include <cppunit/TestFixture.h> 12 #include <cppunit/extensions/HelperMacros.h> 20 #include <unordered_map> 24 using namespace CPPUNIT_NS;
25 using namespace IoUtilities;
26 using namespace ChronoUtilities;
27 using namespace ConversionUtilities;
28 using namespace TestUtilities;
29 using namespace TestUtilities::Literals;
41 enum class SomeEnumClass : uint16 {
53 map<string, int> someMap;
54 unordered_map<string, bool> someHash;
56 multiset<string> someMultiset;
57 unordered_set<string> someUnorderedSet;
58 unordered_multiset<string> someUnorderedMultiset;
60 SomeEnumClass someEnumClass;
67 vector<TestObjectBinary> testObjects;
72 namespace BinaryReflector {
74 template <>
void readCustomType<TestObjectBinary>(BinaryDeserializer &deserializer, TestObjectBinary &customType)
76 deserializer.read(customType.number);
77 deserializer.read(customType.number2);
78 deserializer.read(customType.numbers);
79 deserializer.read(customType.text);
80 deserializer.read(customType.boolean);
81 deserializer.read(customType.someMap);
82 deserializer.read(customType.someHash);
83 deserializer.read(customType.someSet);
84 deserializer.read(customType.someMultiset);
85 deserializer.read(customType.someUnorderedSet);
86 deserializer.read(customType.someUnorderedMultiset);
87 deserializer.read(customType.someEnum);
88 deserializer.read(customType.someEnumClass);
89 deserializer.read(customType.timeSpan);
90 deserializer.read(customType.dateTime);
93 template <>
void writeCustomType<TestObjectBinary>(BinarySerializer &serializer,
const TestObjectBinary &customType)
95 serializer.write(customType.number);
96 serializer.write(customType.number2);
97 serializer.write(customType.numbers);
98 serializer.write(customType.text);
99 serializer.write(customType.boolean);
100 serializer.write(customType.someMap);
101 serializer.write(customType.someHash);
102 serializer.write(customType.someSet);
103 serializer.write(customType.someMultiset);
104 serializer.write(customType.someUnorderedSet);
105 serializer.write(customType.someUnorderedMultiset);
106 serializer.write(customType.someEnum);
107 serializer.write(customType.someEnumClass);
108 serializer.write(customType.timeSpan);
109 serializer.write(customType.dateTime);
112 template <>
void readCustomType<NestingArrayBinary>(BinaryDeserializer &deserializer, NestingArrayBinary &customType)
114 deserializer.read(customType.name);
115 deserializer.read(customType.testObjects);
118 template <>
void writeCustomType<NestingArrayBinary>(BinarySerializer &serializer,
const NestingArrayBinary &customType)
120 serializer.write(customType.name);
121 serializer.write(customType.testObjects);
137 CPPUNIT_TEST(testSerializeSimpleStruct);
138 CPPUNIT_TEST(testDeserializeSimpleStruct);
139 CPPUNIT_TEST(testSerializeNestedStruct);
140 CPPUNIT_TEST(testDeserializeNestedStruct);
141 CPPUNIT_TEST(testSmallSharedPointer);
142 CPPUNIT_TEST(testBigSharedPointer);
143 CPPUNIT_TEST_SUITE_END();
151 void testSerializeSimpleStruct();
152 void testDeserializeSimpleStruct();
153 void testSerializeNestedStruct();
154 void testDeserializeNestedStruct();
155 void assertTestObject(
const TestObjectBinary &deserialized);
156 void testSharedPointer(std::uintptr_t fakePointer);
157 void testSmallSharedPointer();
158 void testBigSharedPointer();
161 vector<unsigned char> m_buffer;
162 TestObjectBinary m_testObj;
163 NestingArrayBinary m_nestedTestObj;
164 vector<unsigned char> m_expectedTestObj;
165 vector<unsigned char> m_expectedNestedTestObj;
175 , m_expectedTestObj({
176 0x00, 0x00, 0x00, 0x05,
177 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x01,
180 0x00, 0x00, 0x00, 0x02,
181 0x00, 0x00, 0x00, 0x03,
182 0x00, 0x00, 0x00, 0x04,
183 0x00, 0x00, 0x00, 0x05,
185 0x73, 0x6F, 0x6D, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74,
188 0x83, 0x62, 0x61, 0x72, 0x00, 0x00, 0x00, 0x13,
189 0x83, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x11,
202 0x00, 0x00, 0x00, 0x01,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xAB,
207 , m_expectedNestedTestObj({
208 0x93, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67,
217 m_testObj.number = 5;
218 m_testObj.number2 = 2.5;
219 m_testObj.numbers = { 1, 2, 3, 4, 5 };
220 m_testObj.text =
"some text";
221 m_testObj.boolean =
true;
222 m_testObj.someMap = {
226 m_testObj.someSet = {
"1",
"2",
"3",
"2" };
227 m_testObj.someMultiset = {
"1",
"2",
"3",
"2" };
228 m_testObj.someEnum = SomeEnumItem2;
229 m_testObj.someEnumClass = SomeEnumClass::Item3;
230 m_testObj.timeSpan = TimeSpan(0xABCD);
231 m_testObj.dateTime = DateTime(0xEFAB);
232 m_nestedTestObj.name =
"struct with nesting";
233 m_expectedNestedTestObj.reserve(m_expectedNestedTestObj.size() + 2 * m_expectedTestObj.size());
234 m_expectedNestedTestObj.insert(m_expectedNestedTestObj.end(), m_expectedTestObj.cbegin(), m_expectedTestObj.cend());
235 m_expectedNestedTestObj.insert(m_expectedNestedTestObj.end(), m_expectedTestObj.cbegin(), m_expectedTestObj.cend());
236 m_nestedTestObj.testObjects.insert(m_nestedTestObj.testObjects.end(), 2, m_testObj);
245 stringstream stream(ios_base::out | ios_base::binary);
246 stream.exceptions(ios_base::failbit | ios_base::badbit);
247 m_buffer.resize(m_expectedTestObj.size());
248 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_buffer.data()), static_cast<streamsize>(m_buffer.size()));
249 m_testObj.toBinary(stream);
251 CPPUNIT_ASSERT_EQUAL(m_expectedTestObj, m_buffer);
256 stringstream stream(ios_base::in | ios_base::binary);
257 stream.exceptions(ios_base::failbit | ios_base::badbit);
258 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_expectedTestObj.data()), static_cast<streamsize>(m_expectedTestObj.size()));
259 const auto deserialized(TestObjectBinary::fromBinary(stream));
265 stringstream stream(ios_base::out | ios_base::binary);
266 stream.exceptions(ios_base::failbit | ios_base::badbit);
267 m_buffer.resize(m_expectedNestedTestObj.size());
268 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_buffer.data()), static_cast<streamsize>(m_buffer.size()));
269 m_nestedTestObj.toBinary(stream);
271 CPPUNIT_ASSERT_EQUAL(m_expectedNestedTestObj, m_buffer);
276 stringstream stream(ios_base::in | ios_base::binary);
277 stream.exceptions(ios_base::failbit | ios_base::badbit);
278 stream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(m_expectedNestedTestObj.data()), static_cast<streamsize>(m_expectedNestedTestObj.size()));
280 const auto deserialized(NestingArrayBinary::fromBinary(stream));
281 CPPUNIT_ASSERT_EQUAL(m_nestedTestObj.name, deserialized.name);
282 for (
const auto &testObj : deserialized.testObjects) {
289 CPPUNIT_ASSERT_EQUAL(m_testObj.number, deserialized.number);
290 CPPUNIT_ASSERT_EQUAL(m_testObj.number2, deserialized.number2);
291 CPPUNIT_ASSERT_EQUAL(m_testObj.numbers, deserialized.numbers);
292 CPPUNIT_ASSERT_EQUAL(m_testObj.text, deserialized.text);
293 CPPUNIT_ASSERT_EQUAL(m_testObj.boolean, deserialized.boolean);
294 CPPUNIT_ASSERT_EQUAL(m_testObj.someMap, deserialized.someMap);
295 CPPUNIT_ASSERT_EQUAL(m_testObj.someHash, deserialized.someHash);
296 CPPUNIT_ASSERT_EQUAL(m_testObj.someSet, deserialized.someSet);
297 CPPUNIT_ASSERT_EQUAL(m_testObj.someMultiset, deserialized.someMultiset);
298 CPPUNIT_ASSERT_EQUAL(m_testObj.someUnorderedSet, deserialized.someUnorderedSet);
299 CPPUNIT_ASSERT_EQUAL(m_testObj.someUnorderedMultiset, deserialized.someUnorderedMultiset);
305 shared_ptr<int> sharedPointer(reinterpret_cast<int *>(fakePointer), [](
int *) {});
308 stringstream stream(ios_base::in | ios_base::out | ios_base::binary);
309 stream.exceptions(ios_base::failbit | ios_base::badbit);
313 serializer.
m_pointer[fakePointer] =
true;
314 serializer.
write(sharedPointer);
318 shared_ptr<int> readPtr;
319 deserializer.
m_pointer[fakePointer] =
"foo";
320 CPPUNIT_ASSERT_THROW(deserializer.
read(readPtr), ConversionUtilities::ConversionException);
321 CPPUNIT_ASSERT(readPtr ==
nullptr);
325 deserializer.
m_pointer[fakePointer] = make_shared<int>(42);
326 deserializer.
read(readPtr);
327 CPPUNIT_ASSERT(readPtr !=
nullptr);
328 CPPUNIT_ASSERT_EQUAL(42, *readPtr);
void testSharedPointer(std::uintptr_t fakePointer)
void write(const Type &pair)
CPPUNIT_TEST_SUITE_REGISTRATION(BinaryReflectorTests)
void testSerializeSimpleStruct()
std::unordered_map< uint64, bool > m_pointer
void testBigSharedPointer()
void assertTestObject(const TestObjectBinary &deserialized)
The BinaryReflectorTests class tests the (de)serializer.
void testSerializeNestedStruct()
void testDeserializeSimpleStruct()
void testSmallSharedPointer()
std::unordered_map< uint64, std::any > m_pointer
void testDeserializeNestedStruct()
The BinarySerializable class provides the CRTP-base for (de)serializable objects.