1 /* Copyright (C) 2013 BMW Group
2 * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3 * Author: Juergen Gehring (juergen.gehring@bmw.de)
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include <CommonAPI/SerializableStruct.h>
8 #include <CommonAPI/SerializableVariant.h>
9 #include <CommonAPI/DBus/DBusInputStream.h>
10 #include <CommonAPI/DBus/DBusOutputStream.h>
12 #include "DBusTestUtils.h"
14 #include <unordered_map>
15 #include <bits/functional_hash.h>
17 #include <gtest/gtest.h>
19 #include <dbus/dbus.h>
24 #include <unordered_map>
25 #include <bits/functional_hash.h>
28 class InputStreamTest: public ::testing::Test {
30 DBusMessage* libdbusMessage;
31 DBusMessageIter libdbusMessageWriteIter;
36 libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
37 ASSERT_TRUE(libdbusMessage != NULL);
38 dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
42 dbus_message_unref(libdbusMessage);
46 TEST_F(InputStreamTest, CanBeConstructed) {
47 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
48 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
51 TEST_F(InputStreamTest, ReadsEmptyMessages) {
52 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
53 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
55 EXPECT_EQ(0, scopedMessage.getBodyLength());
58 TEST_F(InputStreamTest, ReadsBytes) {
60 for (unsigned int i = 0; i < numOfElements; i += 1) {
61 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BYTE, &val);
64 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
65 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
67 EXPECT_EQ(numOfElements, scopedMessage.getBodyLength());
68 for (unsigned int i = 0; i < numOfElements; i += 1) {
71 EXPECT_EQ(val, readVal);
75 TEST_F(InputStreamTest, ReadsBools) {
76 dbus_bool_t f = FALSE;
78 for (unsigned int i = 0; i < numOfElements; i += 2) {
79 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &t);
80 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &f);
83 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
84 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
86 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
87 for (unsigned int i = 0; i < numOfElements; i += 2) {
90 EXPECT_EQ(t, readVal);
92 EXPECT_EQ(f, readVal);
96 TEST_F(InputStreamTest, ReadsUint16) {
98 uint16_t val = 0xffff;
99 for (unsigned int i = 0; i < numOfElements; i += 1) {
100 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT16, &val);
103 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
104 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
106 EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
107 for (unsigned int i = 0; i < numOfElements; i += 1) {
110 EXPECT_EQ(val, readVal);
114 TEST_F(InputStreamTest, ReadsInt16) {
116 int16_t val = 0x7fff;
117 for (unsigned int i = 0; i < numOfElements; i += 1) {
118 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT16, &val);
121 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
122 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
124 EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
125 for (unsigned int i = 0; i < numOfElements; i += 1) {
128 EXPECT_EQ(val, readVal);
132 TEST_F(InputStreamTest, ReadsUint32) {
134 uint32_t val = 0xffffffff;
135 for (unsigned int i = 0; i < numOfElements; i += 1) {
136 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT32, &val);
139 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
140 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
142 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
143 for (unsigned int i = 0; i < numOfElements; i += 1) {
146 EXPECT_EQ(val, readVal);
150 TEST_F(InputStreamTest, ReadsInt32) {
152 int32_t val = 0x7fffffff;
153 for (unsigned int i = 0; i < numOfElements; i += 1) {
154 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT32, &val);
157 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
158 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
160 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
161 for (unsigned int i = 0; i < numOfElements; i += 1) {
164 EXPECT_EQ(val, readVal);
168 TEST_F(InputStreamTest, ReadsUint64) {
170 uint64_t val = 0xffffffffffffffff;
171 for (unsigned int i = 0; i < numOfElements; i += 1) {
172 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT64, &val);
175 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
176 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
178 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
179 for (unsigned int i = 0; i < numOfElements; i += 1) {
182 EXPECT_EQ(val, readVal);
186 TEST_F(InputStreamTest, ReadsInt64) {
188 int64_t val = 0x7fffffffffffffff;
189 for (unsigned int i = 0; i < numOfElements; i += 1) {
190 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT64, &val);
193 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
194 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
196 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
197 for (unsigned int i = 0; i < numOfElements; i += 1) {
200 EXPECT_EQ(val, readVal);
204 TEST_F(InputStreamTest, ReadsDoubles) {
207 for (unsigned int i = 0; i < numOfElements; i += 1) {
208 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_DOUBLE, &val);
211 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
212 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
214 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
215 for (unsigned int i = 0; i < numOfElements; i += 1) {
218 EXPECT_EQ(val, readVal);
222 TEST_F(InputStreamTest, ReadsStrings) {
224 std::string val = "hai";
225 for (unsigned int i = 0; i < numOfElements; i += 1) {
226 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_STRING, &val);
229 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
230 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
232 EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
233 for (unsigned int i = 0; i < numOfElements; i += 1) {
236 EXPECT_EQ(val, readVal);
245 struct TestSerializableStruct: CommonAPI::SerializableStruct {
252 virtual void readFromInputStream(CommonAPI::InputStream& inputStream) {
253 inputStream >> a >> b >> c >> d >> e;
256 virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
257 outputStream << a << b << c << d << e;
260 static void writeToTypeOutputStream(CommonAPI::TypeOutputStream& typeOutputStream) {
261 typeOutputStream.writeUInt32Type();
262 typeOutputStream.writeInt16Type();
263 typeOutputStream.writeBoolType();
264 typeOutputStream.writeStringType();
265 typeOutputStream.writeDoubleType();
269 bool operator==(const TestSerializableStruct& lhs, const TestSerializableStruct& rhs) {
273 return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d) && (lhs.e == rhs.e);
279 TEST_F(InputStreamTest, ReadsStructs) {
281 bmw::test::TestSerializableStruct testStruct;
284 testStruct.c = FALSE;
285 testStruct.d = "Hello all";
286 testStruct.e = 3.414;
288 DBusMessageIter subIter;
289 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
290 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_UINT32, &testStruct.a);
291 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT16, &testStruct.b);
292 dbus_bool_t dbusBool = static_cast<dbus_bool_t>(testStruct.c);
293 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BOOLEAN, &dbusBool);
294 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &testStruct.d);
295 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_DOUBLE, &testStruct.e);
296 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
298 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
299 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
301 //40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
302 // + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
303 EXPECT_EQ(40, scopedMessage.getBodyLength());
305 bmw::test::TestSerializableStruct verifyStruct;
306 inStream >> verifyStruct;
307 EXPECT_EQ(testStruct.a, verifyStruct.a);
308 EXPECT_EQ(testStruct.b, verifyStruct.b);
309 EXPECT_EQ(testStruct.c, verifyStruct.c);
310 EXPECT_EQ(testStruct.d, verifyStruct.d);
311 EXPECT_EQ(testStruct.e, verifyStruct.e);
314 TEST_F(InputStreamTest, ReadsArrays) {
316 std::vector<int32_t> testVector;
317 int32_t val1 = 0xffffffff;
318 int32_t val2 = 0x7fffffff;
319 for (unsigned int i = 0; i < numOfElements; i += 2) {
320 testVector.push_back(val1);
321 testVector.push_back(val2);
324 DBusMessageIter subIter;
325 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_ARRAY, "i", &subIter);
326 for (unsigned int i = 0; i < numOfElements; i++) {
327 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT32, &testVector[i]);
329 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
331 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
332 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
334 EXPECT_EQ(scopedMessage.getBodyLength(), numOfElements*4 + 4);
335 std::vector<int32_t> verifyVector;
336 inStream >> verifyVector;
339 for (unsigned int i = 0; i < numOfElements; i += 2) {
340 res1 = verifyVector[i];
341 EXPECT_EQ(val1, res1);
342 res2 = verifyVector[i + 1];
343 EXPECT_EQ(val2, res2);
347 TEST_F(InputStreamTest, ReadsArraysInArrays) {
348 size_t numOfElements = 2;
349 DBusMessage* dbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
350 ASSERT_TRUE(dbusMessage != NULL);
352 DBusMessageIter writeIter;
353 dbus_message_iter_init_append(dbusMessage, &writeIter);
355 std::vector<std::vector<int32_t>> testVector;
356 int32_t val1 = 0xffffffff;
357 int32_t val2 = 0x7fffffff;
358 for (unsigned int i = 0; i < numOfElements; i++) {
359 std::vector<int32_t> inner;
360 for (unsigned int j = 0; j < numOfElements; j += 2) {
361 inner.push_back(val1);
362 inner.push_back(val2);
364 testVector.push_back(inner);
367 DBusMessageIter subIter;
368 dbus_message_iter_open_container(&writeIter, DBUS_TYPE_ARRAY, "ai", &subIter);
369 for (unsigned int i = 0; i < numOfElements; i++) {
370 DBusMessageIter subsubIter;
371 dbus_message_iter_open_container(&subIter, DBUS_TYPE_ARRAY, "i", &subsubIter);
372 for (unsigned int j = 0; j < numOfElements; j++) {
373 dbus_message_iter_append_basic(&subsubIter, DBUS_TYPE_INT32, &(testVector[i][j]));
375 dbus_message_iter_close_container(&subIter, &subsubIter);
377 dbus_message_iter_close_container(&writeIter, &subIter);
379 CommonAPI::DBus::DBusMessage scopedMessage(dbusMessage);
380 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
382 // 5*5*int32_t + 5*lengthField_inner(int32_t) + lengthField_outer(int32_t)
383 EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, scopedMessage.getBodyLength());
384 std::vector<std::vector<int32_t>> verifyVector;
385 inStream >> verifyVector;
389 for (unsigned int i = 0; i < numOfElements; i++) {
390 std::vector<int32_t> innerVerify = verifyVector[i];
391 for (unsigned int j = 0; j < numOfElements; j += 2) {
392 res1 = innerVerify[j];
393 EXPECT_EQ(val1, res1);
394 res2 = innerVerify[j + 1];
395 EXPECT_EQ(val2, res2);
400 TEST_F(InputStreamTest, ReadsInt32Variants) {
401 typedef CommonAPI::Variant<int32_t, double, std::string> TestedVariantType;
404 int8_t variantTypeIndex = 3;
406 for (unsigned int i = 0; i < numOfElements; i += 1) {
407 DBusMessageIter subIter;
408 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
409 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
410 DBusMessageIter subSubIter;
411 dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "i", &subSubIter);
412 dbus_message_iter_append_basic(&subSubIter, DBUS_TYPE_INT32, &fromInt);
413 dbus_message_iter_close_container(&subIter, &subSubIter);
414 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
417 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
418 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
420 TestedVariantType referenceVariant(fromInt);
422 EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
423 for (unsigned int i = 0; i < numOfElements; i += 1) {
424 TestedVariantType readVariant;
425 inStream >> readVariant;
427 //TODO: EXPECT_NO_THROW (oder so)
428 int32_t actualResult = readVariant.get<int32_t>();
430 bool varEq = (referenceVariant == readVariant);
432 EXPECT_EQ(fromInt, actualResult);
436 TEST_F(InputStreamTest, ReadsStringVariants) {
437 typedef CommonAPI::Variant<int32_t, double, std::string> TestedVariantType;
439 std::string fromString = "Hello World with CommonAPI Variants!";
440 int8_t variantTypeIndex = 1;
442 for (unsigned int i = 0; i < numOfElements; i += 1) {
443 DBusMessageIter subIter;
444 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
445 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
446 DBusMessageIter subSubIter;
447 dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "s", &subSubIter);
448 dbus_message_iter_append_basic(&subSubIter, DBUS_TYPE_STRING, &fromString);
449 dbus_message_iter_close_container(&subIter, &subSubIter);
450 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
453 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
454 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
456 TestedVariantType referenceVariant(fromString);
458 //Variant: type-index(1) + signature(2) + padding(1) + stringLength(4) + string(37) = 45
459 // +struct-padding inbetween (alignment 8)
460 EXPECT_EQ(numOfElements * (1+3+4+fromString.length()+1) + (numOfElements - 1) * (8-((fromString.length()+1)%8)) , scopedMessage.getBodyLength());
461 for (unsigned int i = 0; i < numOfElements; i += 1) {
462 TestedVariantType readVariant;
463 inStream >> readVariant;
465 std::string actualResult = readVariant.get<std::string>();
467 bool variantsAreEqual = (referenceVariant == readVariant);
468 EXPECT_TRUE(variantsAreEqual);
469 EXPECT_EQ(fromString, actualResult);
474 TEST_F(InputStreamTest, ReadsVariantsWithAnArrayOfStrings) {
475 typedef CommonAPI::Variant<int32_t, double, std::vector<std::string>> TestedVariantType;
477 std::string testString1 = "Hello World with CommonAPI Variants!";
478 std::string testString2 = "What a beautiful world if there are working Arrays within Variants!!";
479 int8_t variantTypeIndex = 1;
481 std::vector<std::string> testInnerVector;
483 for (unsigned int i = 0; i < numOfElements; i += 2) {
484 testInnerVector.push_back(testString1);
485 testInnerVector.push_back(testString2);
488 for (unsigned int i = 0; i < numOfElements; i += 1) {
489 DBusMessageIter subIter;
490 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
491 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
492 DBusMessageIter subSubIter;
493 dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "as", &subSubIter);
495 DBusMessageIter innerArrayIter;
496 dbus_message_iter_open_container(&subSubIter, DBUS_TYPE_ARRAY, "s", &innerArrayIter);
497 for (unsigned int i = 0; i < numOfElements; i++) {
498 dbus_message_iter_append_basic(&innerArrayIter, DBUS_TYPE_STRING, &testInnerVector[i]);
500 dbus_message_iter_close_container(&subSubIter, &innerArrayIter);
502 dbus_message_iter_close_container(&subIter, &subSubIter);
503 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
506 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
507 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
509 TestedVariantType referenceVariant(testInnerVector);
511 //Variant: structAlign + type-index(1) + variantSignature(4) + padding(3) + arrayLength(4) + stringLength(4) +
512 // string(37) + padding(3) + stringLength(4) + string(69) = 129
513 EXPECT_EQ(129 + 7 + 129, scopedMessage.getBodyLength());
514 for (unsigned int i = 0; i < numOfElements; i += 1) {
515 TestedVariantType readVariant;
516 inStream >> readVariant;
518 std::vector<std::string> actualResult = readVariant.get<std::vector<std::string>>();
520 bool variantsAreEqual = (referenceVariant == readVariant);
521 EXPECT_TRUE(variantsAreEqual);
522 EXPECT_EQ(testInnerVector, actualResult);
528 TEST_F(InputStreamTest, ReadsVariantsWithVariants) {
529 typedef CommonAPI::Variant<int8_t, uint64_t, CommonAPI::ByteBuffer> InnerVariantType;
531 typedef CommonAPI::Variant<int32_t,
537 int8_t outerVariantTypeIndex = 1;
538 int8_t innerVariant1TypeIndex = 1;
539 int8_t innerVariant2TypeIndex = 3;
541 const uint32_t byteBufferElementCount = numOfElements*10;
543 CommonAPI::ByteBuffer innerVariant1Value;
544 for (unsigned int i = 0; i < byteBufferElementCount; ++i) {
545 innerVariant1Value.push_back((char) (i+40));
548 int8_t innerVariant2Value = -55;
551 DBusMessageIter outerVariantStructIter;
552 DBusMessageIter outerVariantActualIter;
553 DBusMessageIter innerVariantStructIter;
554 DBusMessageIter innerVariantActualIterator;
555 DBusMessageIter innerArrayIter;
558 //begin 1. outer variant
559 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &outerVariantStructIter);
560 dbus_message_iter_append_basic(&outerVariantStructIter, DBUS_TYPE_BYTE, &outerVariantTypeIndex);
561 dbus_message_iter_open_container(&outerVariantStructIter, DBUS_TYPE_VARIANT, "(yv)", &outerVariantActualIter);
563 //begin inner variant
564 dbus_message_iter_open_container(&outerVariantActualIter, DBUS_TYPE_STRUCT, NULL, &innerVariantStructIter);
565 dbus_message_iter_append_basic(&innerVariantStructIter, DBUS_TYPE_BYTE, &innerVariant1TypeIndex);
566 dbus_message_iter_open_container(&innerVariantStructIter, DBUS_TYPE_VARIANT, "ay", &innerVariantActualIterator);
568 //begin inner variant content
569 dbus_message_iter_open_container(&innerVariantActualIterator, DBUS_TYPE_ARRAY, "y", &innerArrayIter);
570 for (unsigned int i = 0; i < byteBufferElementCount; i++) {
571 dbus_message_iter_append_basic(&innerArrayIter, DBUS_TYPE_BYTE, &innerVariant1Value[i]);
573 dbus_message_iter_close_container(&innerVariantActualIterator, &innerArrayIter);
574 //end inner variant content
576 dbus_message_iter_close_container(&innerVariantStructIter, &innerVariantActualIterator);
577 dbus_message_iter_close_container(&outerVariantActualIter, &innerVariantStructIter);
580 dbus_message_iter_close_container(&outerVariantStructIter, &outerVariantActualIter);
581 dbus_message_iter_close_container(&libdbusMessageWriteIter, &outerVariantStructIter);
582 //end 1. outer variant
585 //begin 2. outer variant
586 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &outerVariantStructIter);
587 dbus_message_iter_append_basic(&outerVariantStructIter, DBUS_TYPE_BYTE, &outerVariantTypeIndex);
588 dbus_message_iter_open_container(&outerVariantStructIter, DBUS_TYPE_VARIANT, "(yv)", &outerVariantActualIter);
590 //begin inner variant
591 dbus_message_iter_open_container(&outerVariantActualIter, DBUS_TYPE_STRUCT, NULL, &innerVariantStructIter);
592 dbus_message_iter_append_basic(&innerVariantStructIter, DBUS_TYPE_BYTE, &innerVariant2TypeIndex);
593 dbus_message_iter_open_container(&innerVariantStructIter, DBUS_TYPE_VARIANT, "y", &innerVariantActualIterator);
595 //begin inner variant content
596 dbus_message_iter_append_basic(&innerVariantActualIterator, DBUS_TYPE_BYTE, &innerVariant2Value);
597 //end inner variant content
599 dbus_message_iter_close_container(&innerVariantStructIter, &innerVariantActualIterator);
600 dbus_message_iter_close_container(&outerVariantActualIter, &innerVariantStructIter);
603 dbus_message_iter_close_container(&outerVariantStructIter, &outerVariantActualIter);
604 dbus_message_iter_close_container(&libdbusMessageWriteIter, &outerVariantStructIter);
605 //end 2. outer variant
608 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
609 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
611 InnerVariantType referenceInnerVariant1(innerVariant1Value);
612 InnerVariantType referenceInnerVariant2(innerVariant2Value);
614 TestedVariantType referenceVariant1(referenceInnerVariant1);
615 TestedVariantType referenceVariant2(referenceInnerVariant2);
617 //Variant1: type-index(1) + varSigLen(1) + varSig(2) + struct-padding(4) + inner-type-index(1) + varLen(1) + varSig(3) +
618 // padding(3) + byteBufferLength(4) + byteBuffer(20) = 40
619 //Variant2: type-index(1) + varSigLen(1) + varSig(2) + struct-padding(4) + inner-type-index(1) + varLen(1) + varSig(2) +
622 EXPECT_EQ(53, scopedMessage.getBodyLength());
624 TestedVariantType readVariant1;
625 TestedVariantType readVariant2;
626 inStream >> readVariant1;
627 inStream >> readVariant2;
628 EXPECT_EQ(referenceVariant1, readVariant1);
629 EXPECT_EQ(referenceVariant2, readVariant2);
631 InnerVariantType readInnerVariant1 = readVariant1.get<InnerVariantType>();
632 InnerVariantType readInnerVariant2 = readVariant2.get<InnerVariantType>();
633 EXPECT_EQ(referenceInnerVariant1, readInnerVariant1);
634 EXPECT_EQ(referenceInnerVariant2, readInnerVariant2);
636 CommonAPI::ByteBuffer readInnerValue1 = readInnerVariant1.get<CommonAPI::ByteBuffer>();
637 int8_t readInnerValue2 = readInnerVariant2.get<int8_t>();
638 EXPECT_EQ(innerVariant1Value, readInnerValue1);
639 EXPECT_EQ(innerVariant2Value, readInnerValue2);
643 TEST_F(InputStreamTest, ReadsVariantsWithStructs) {
644 typedef CommonAPI::Variant<int32_t,
647 bmw::test::TestSerializableStruct>
650 int8_t variantTypeIndex = 1;
652 bmw::test::TestSerializableStruct testStruct;
655 testStruct.c = false;
656 testStruct.d = "Hello all!";
657 testStruct.e = 3.414;
660 DBusMessageIter variantStructIter;
661 DBusMessageIter variantActualIter;
662 DBusMessageIter innerStructIter;
666 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &variantStructIter);
667 dbus_message_iter_append_basic(&variantStructIter, DBUS_TYPE_BYTE, &variantTypeIndex);
668 dbus_message_iter_open_container(&variantStructIter, DBUS_TYPE_VARIANT, "(unbsd)", &variantActualIter);
670 //begin variant content
671 dbus_message_iter_open_container(&variantActualIter, DBUS_TYPE_STRUCT, NULL, &innerStructIter);
673 dbus_bool_t dbusBool = 0;
674 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_UINT32, &testStruct.a);
675 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_INT16, &testStruct.b);
676 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_BOOLEAN, &dbusBool);
677 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_STRING, &testStruct.d);
678 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_DOUBLE, &testStruct.e);
680 dbus_message_iter_close_container(&variantActualIter, &innerStructIter);
681 //end variant content
683 dbus_message_iter_close_container(&variantStructIter, &variantActualIter);
684 dbus_message_iter_close_container(&libdbusMessageWriteIter, &variantStructIter);
687 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
688 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
689 TestedVariantType referenceVariant(testStruct);
691 //type-index(1) + varSigLen(1) + varSig(8) + struct-padding(6) + uint32(4) + int16(2) + padding(2) + bool(4) +
692 //stringLen(4) + stringVal(11) + padding(5) + double(8) = 56
693 EXPECT_EQ(56, scopedMessage.getBodyLength());
695 TestedVariantType readVariant;
696 inStream >> readVariant;
698 bmw::test::TestSerializableStruct readStruct = readVariant.get<bmw::test::TestSerializableStruct>();
699 EXPECT_EQ(testStruct.a, readStruct.a);
700 EXPECT_EQ(testStruct.b, readStruct.b);
701 EXPECT_EQ(testStruct.c, readStruct.c);
702 EXPECT_EQ(testStruct.d, readStruct.d);
703 EXPECT_EQ(testStruct.e, readStruct.e);
704 EXPECT_EQ(testStruct, readStruct);
705 EXPECT_EQ(referenceVariant, readVariant);
709 TEST_F(InputStreamTest, ReadsVariantsWithAnArrayOfStructs) {
710 typedef CommonAPI::Variant<int32_t, double, std::vector<bmw::test::TestSerializableStruct>> TestedVariantType;
712 bmw::test::TestSerializableStruct testStruct;
715 testStruct.c = false;
716 testStruct.d = "Hello all!";
717 testStruct.e = 3.414;
719 int8_t variantTypeIndex = 1;
721 DBusMessageIter subIter;
722 DBusMessageIter subSubIter;
723 DBusMessageIter innerArrayIter;
724 DBusMessageIter innerStructIter;
727 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
728 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
729 dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "a(unbsd)", &subSubIter);
732 dbus_message_iter_open_container(&subSubIter, DBUS_TYPE_ARRAY, "(unbsd)", &innerArrayIter);
735 dbus_message_iter_open_container(&innerArrayIter, DBUS_TYPE_STRUCT, NULL, &innerStructIter);
737 dbus_bool_t dbusBool = 0;
738 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_UINT32, &testStruct.a);
739 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_INT16, &testStruct.b);
740 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_BOOLEAN, &dbusBool);
741 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_STRING, &testStruct.d);
742 dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_DOUBLE, &testStruct.e);
744 dbus_message_iter_close_container(&innerArrayIter, &innerStructIter);
747 dbus_message_iter_close_container(&subSubIter, &innerArrayIter);
750 dbus_message_iter_close_container(&subIter, &subSubIter);
751 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
754 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
755 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
757 std::vector<bmw::test::TestSerializableStruct> referenceInnerVector;
758 referenceInnerVector.push_back(testStruct);
759 TestedVariantType referenceVariant(referenceInnerVector);
761 //type-index(1) + varSigLen(1) + variantSig(9) + padding(1) + arrayLength(4) + uint32(4) + int16(2) + padding(2)
762 //bool(4) + stringLength(4) + string(11) + padding(5) + double(8) = 56
763 EXPECT_EQ(56, scopedMessage.getBodyLength());
765 TestedVariantType readVariant;
766 inStream >> readVariant;
768 std::vector<bmw::test::TestSerializableStruct> actualResult = readVariant.get<std::vector<bmw::test::TestSerializableStruct>>();
769 bmw::test::TestSerializableStruct readStruct = actualResult[0];
771 EXPECT_EQ(testStruct.a, readStruct.a);
772 EXPECT_EQ(testStruct.b, readStruct.b);
773 EXPECT_EQ(testStruct.c, readStruct.c);
774 EXPECT_EQ(testStruct.d, readStruct.d);
775 EXPECT_EQ(testStruct.e, readStruct.e);
776 EXPECT_EQ(testStruct, readStruct);
777 EXPECT_EQ(referenceInnerVector, actualResult);
778 EXPECT_EQ(referenceVariant, readVariant);
782 int main(int argc, char** argv) {
783 ::testing::InitGoogleTest(&argc, argv);
784 return RUN_ALL_TESTS();