Imported Upstream version 1.2.0
[platform/upstream/iotivity.git] / resource / unittests / OCRepresentationEncodingTest.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <gtest/gtest.h>
22 #include <OCApi.h>
23 #include <OCRepresentation.h>
24 #include <octypes.h>
25 #include <ocstack.h>
26 #include <ocpayload.h>
27 #include <ocpayloadcbor.h>
28 #include <oic_malloc.h>
29 #include <oic_string.h>
30 #include "payload_logging.h"
31
32 bool operator==(const OCByteString& lhs, const OCByteString& rhs)
33 {
34     bool result = (lhs.len == rhs.len);
35     if (result)
36     {
37         result = (memcmp(lhs.bytes, rhs.bytes, lhs.len) == 0);
38     }
39     return result;
40 }
41
42 namespace OC
43 {
44     bool operator==(const OC::NullType&, const OC::NullType&)
45     {
46         return true;
47     }
48
49     bool operator==(const OC::OCRepresentation& lhs, const OC::OCRepresentation& rhs)
50     {
51         return lhs.getUri() == rhs.getUri() &&
52             lhs.getChildren() == rhs.getChildren() &&
53             lhs.getResourceInterfaces() == rhs.getResourceInterfaces() &&
54             lhs.getResourceTypes() == rhs.getResourceTypes() &&
55             lhs.m_values == rhs.m_values;
56     }
57 }
58 // these tests validate the OCRepresentation->OCPayload, OCPayload->CBOR,
59 // CBOR->OCPayload and OCPayload->OCRepresentation conversions
60 namespace OCRepresentationEncodingTest
61 {
62     static const char sid1[] = "646F6F72-4465-7669-6365-555549443030";
63     static const char devicename1[] = "device name";
64     static const char specver1[] = "spec version";
65     static const char dmver1[] = "res.1.1.0";
66     static OCStringLL *types = NULL;
67     // Device Payloads
68     TEST(DeviceDiscoveryEncoding, Normal)
69     {
70         OCResourcePayloadAddStringLL(&types, "oic.wk.d");
71         OCResourcePayloadAddStringLL(&types, "oic.d.tv");
72
73         OCDevicePayload* device = OCDevicePayloadCreate(
74                 sid1,
75                 devicename1,
76                 types,
77                 specver1,
78                 dmver1);
79         EXPECT_TRUE(device);
80         EXPECT_STREQ(sid1, device->sid);
81         EXPECT_STREQ(devicename1, device->deviceName);
82         EXPECT_STREQ(specver1, device->specVersion);
83         EXPECT_TRUE(device->dataModelVersions);
84         EXPECT_STREQ("res.1.1.0", device->dataModelVersions->value);
85         EXPECT_FALSE(device->dataModelVersions->next);
86         EXPECT_EQ(PAYLOAD_TYPE_DEVICE, ((OCPayload *)device)->type);
87         EXPECT_STREQ("oic.wk.d", device->types->value);
88         EXPECT_STREQ("oic.d.tv", device->types->next->value);
89
90         uint8_t* cborData;
91         size_t cborSize;
92         OCPayload* parsedDevice;
93         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)device, &cborData, &cborSize));
94         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedDevice, PAYLOAD_TYPE_DEVICE,
95                     cborData, cborSize));
96         OICFree(cborData);
97
98         EXPECT_STREQ(device->sid, ((OCDevicePayload*)parsedDevice)->sid);
99         EXPECT_STREQ(device->deviceName, ((OCDevicePayload*)parsedDevice)->deviceName);
100         EXPECT_STREQ(device->specVersion, ((OCDevicePayload*)parsedDevice)->specVersion);
101         EXPECT_STREQ(device->dataModelVersions->value, ((OCDevicePayload*)parsedDevice)->dataModelVersions->value);
102         EXPECT_STREQ("oic.wk.d", ((OCDevicePayload*)parsedDevice)->types->value);
103         EXPECT_STREQ("oic.d.tv", ((OCDevicePayload*)parsedDevice)->types->next->value);
104         EXPECT_EQ(device->base.type, ((OCDevicePayload*)parsedDevice)->base.type);
105
106         OCPayloadDestroy((OCPayload*)device);
107
108         OC::MessageContainer mc1;
109         mc1.setPayload(parsedDevice);
110         EXPECT_EQ(1u, mc1.representations().size());
111         const OC::OCRepresentation &r1 = mc1.representations()[0];
112         EXPECT_STREQ(sid1, r1.getValue<std::string>(OC_RSRVD_DEVICE_ID).c_str());
113         EXPECT_STREQ(devicename1, r1.getValue<std::string>(OC_RSRVD_DEVICE_NAME).c_str());
114         EXPECT_STREQ(specver1, r1.getValue<std::string>(OC_RSRVD_SPEC_VERSION).c_str());
115         EXPECT_STREQ("res.1.1.0", r1.getDataModelVersions()[0].c_str());
116
117         OCPayloadDestroy(parsedDevice);
118
119         static const char dmver2[] = "res.1.1.0,sh.1.1.0";
120         device = OCDevicePayloadCreate(
121                      sid1,
122                      devicename1,
123                      types,
124                      specver1,
125                      dmver2);
126
127         EXPECT_STREQ("res.1.1.0", device->dataModelVersions->value);
128         EXPECT_TRUE(device->dataModelVersions->next);
129         EXPECT_STREQ("sh.1.1.0", device->dataModelVersions->next->value);
130         EXPECT_FALSE(device->dataModelVersions->next->next);
131         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)device, &cborData, &cborSize));
132         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedDevice, PAYLOAD_TYPE_DEVICE,
133                                               cborData, cborSize));
134         OICFree(cborData);
135         EXPECT_STREQ(device->dataModelVersions->value,
136                      ((OCDevicePayload *)parsedDevice)->dataModelVersions->value);
137         EXPECT_STREQ(device->dataModelVersions->next->value,
138                      ((OCDevicePayload *)parsedDevice)->dataModelVersions->next->value);
139         OCPayloadDestroy((OCPayload *)device);
140         OC::MessageContainer mc2;
141         mc2.setPayload(parsedDevice);
142         EXPECT_EQ(1u, mc2.representations().size());
143         const OC::OCRepresentation r2 = mc2.representations()[0];
144         EXPECT_STREQ("res.1.1.0", r2.getDataModelVersions()[0].c_str());
145         EXPECT_STREQ("sh.1.1.0", r2.getDataModelVersions()[1].c_str());
146
147         OCPayloadDestroy(parsedDevice);
148     }
149
150     static const char uri1[] = "/testuri";
151     static char pfid1[] = "pfid";
152     static char mfgnm1[] = "mfgnm";
153     static char mfgurl1[] = "mfgurl";
154     static char modelnum1[] = "modelnum";
155     static char dom1[] = "dom";
156     static char pfver1[] = "pfver";
157     static char osver1[] = "osver";
158     static char hwver1[] = "hwver";
159     static char fwver1[] = "fwver";
160     static char url1[] = "url";
161     static char time1[] = "time";
162
163     // Platform Payloads
164     TEST(PlatformDiscoveryEncoding, Normal)
165     {
166         OCPlatformInfo info {pfid1, mfgnm1, mfgurl1, modelnum1, dom1, pfver1, osver1, hwver1,
167             fwver1, url1, time1};
168         OCPlatformPayload* platform = OCPlatformPayloadCreate(&info);
169         EXPECT_EQ(PAYLOAD_TYPE_PLATFORM, ((OCPayload*)platform)->type);
170         EXPECT_STREQ(pfid1, platform->info.platformID);
171         EXPECT_STREQ(mfgnm1, platform->info.manufacturerName);
172         EXPECT_STREQ(mfgurl1, platform->info.manufacturerUrl);
173         EXPECT_STREQ(modelnum1, platform->info.modelNumber);
174         EXPECT_STREQ(dom1, platform->info.dateOfManufacture);
175         EXPECT_STREQ(pfver1, platform->info.platformVersion);
176         EXPECT_STREQ(osver1, platform->info.operatingSystemVersion);
177         EXPECT_STREQ(hwver1, platform->info.hardwareVersion);
178         EXPECT_STREQ(fwver1, platform->info.firmwareVersion);
179         EXPECT_STREQ(url1, platform->info.supportUrl);
180         EXPECT_STREQ(time1, platform->info.systemTime);
181         EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, platform->interfaces->value);
182         EXPECT_STREQ(OC_RSRVD_INTERFACE_READ, platform->interfaces->next->value);
183         EXPECT_STREQ(OC_RSRVD_RESOURCE_TYPE_PLATFORM, platform->rt->value);
184
185         uint8_t* cborData;
186         size_t cborSize;
187         OCPayload* parsedPlatform;
188         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)platform, &cborData, &cborSize));
189         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedPlatform, PAYLOAD_TYPE_PLATFORM,
190                     cborData, cborSize));
191         OICFree(cborData);
192
193         EXPECT_EQ(platform->base.type, ((OCPlatformPayload*)parsedPlatform)->base.type);
194         OCPlatformPayload* platform2 = (OCPlatformPayload*)parsedPlatform;
195         EXPECT_STREQ(platform->info.platformID, platform2->info.platformID);
196         EXPECT_STREQ(platform->info.manufacturerName, platform->info.manufacturerName);
197         EXPECT_STREQ(platform->info.manufacturerUrl, platform->info.manufacturerUrl);
198         EXPECT_STREQ(platform->info.modelNumber, platform->info.modelNumber);
199         EXPECT_STREQ(platform->info.dateOfManufacture, platform->info.dateOfManufacture);
200         EXPECT_STREQ(platform->info.platformVersion, platform->info.platformVersion);
201         EXPECT_STREQ(platform->info.operatingSystemVersion, platform->info.operatingSystemVersion);
202         EXPECT_STREQ(platform->info.hardwareVersion, platform->info.hardwareVersion);
203         EXPECT_STREQ(platform->info.firmwareVersion, platform->info.firmwareVersion);
204         EXPECT_STREQ(platform->info.supportUrl, platform->info.supportUrl);
205         EXPECT_STREQ(platform->info.systemTime, platform2->info.systemTime);
206         EXPECT_STREQ(platform->interfaces->value, platform2->interfaces->value);
207         EXPECT_STREQ(platform->rt->value, platform2->rt->value);
208
209         OCPayloadDestroy((OCPayload*)platform);
210
211         OC::MessageContainer mc;
212         mc.setPayload(parsedPlatform);
213         EXPECT_EQ(1u, mc.representations().size());
214         const OC::OCRepresentation& r = mc.representations()[0];
215         EXPECT_STREQ(pfid1, r.getValue<std::string>(OC_RSRVD_PLATFORM_ID).c_str());
216         EXPECT_STREQ(mfgnm1, r.getValue<std::string>(OC_RSRVD_MFG_NAME).c_str());
217         EXPECT_STREQ(mfgurl1, r.getValue<std::string>(OC_RSRVD_MFG_URL).c_str());
218         EXPECT_STREQ(modelnum1, r.getValue<std::string>(OC_RSRVD_MODEL_NUM).c_str());
219         EXPECT_STREQ(dom1, r.getValue<std::string>(OC_RSRVD_MFG_DATE).c_str());
220         EXPECT_STREQ(pfver1, r.getValue<std::string>(OC_RSRVD_PLATFORM_VERSION).c_str());
221         EXPECT_STREQ(osver1, r.getValue<std::string>(OC_RSRVD_OS_VERSION).c_str());
222         EXPECT_STREQ(hwver1, r.getValue<std::string>(OC_RSRVD_HARDWARE_VERSION).c_str());
223         EXPECT_STREQ(fwver1, r.getValue<std::string>(OC_RSRVD_FIRMWARE_VERSION).c_str());
224         EXPECT_STREQ(url1, r.getValue<std::string>(OC_RSRVD_SUPPORT_URL).c_str());
225         EXPECT_STREQ(time1, r.getValue<std::string>(OC_RSRVD_SYSTEM_TIME).c_str());
226
227         OCPayloadDestroy(parsedPlatform);
228     }
229     TEST(PresencePayload, Normal)
230     {
231         uint32_t maxAge = 0;
232         uint32_t sequenceNumber = 0;
233         OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
234         OCPresencePayload *presence = OCPresencePayloadCreate(sequenceNumber, maxAge, trigger, uri1);
235
236         uint8_t* cborData;
237         size_t cborSize;
238         OCPayload* cparsed;
239         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)presence, &cborData, &cborSize));
240         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_PRESENCE,
241                     cborData, cborSize));
242         OCPayloadDestroy((OCPayload*)presence);
243         OICFree(cborData);
244
245         OCPresencePayload* parsed = ((OCPresencePayload*)cparsed);
246         EXPECT_EQ(sequenceNumber, parsed->sequenceNumber);
247         EXPECT_EQ(maxAge, parsed->maxAge);
248         EXPECT_EQ(trigger, parsed->trigger);
249         EXPECT_STREQ(uri1, parsed->resourceType);
250
251         OCPayloadDestroy(cparsed);
252     }
253     // Representation Payloads
254     TEST(RepresentationEncoding, BaseAttributeTypes)
255     {
256         OC::OCRepresentation startRep;
257         startRep.setNULL("NullAttr");
258         startRep.setValue("IntAttr", 77);
259         startRep.setValue("DoubleAttr", 3.333);
260         startRep.setValue("BoolAttr", true);
261         startRep.setValue("StringAttr", std::string("String attr"));
262
263         uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
264                             0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
265                            };
266         OCByteString byteString = {binval, sizeof(binval)};
267         startRep.setValue("ByteStringAttr", byteString);
268
269         OC::MessageContainer mc1;
270         mc1.addRepresentation(startRep);
271
272         OCRepPayload* cstart = mc1.getPayload();
273         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
274
275         uint8_t* cborData;
276         size_t cborSize;
277         OCPayload* cparsed;
278         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
279         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
280                     cborData, cborSize));
281         OCPayloadDestroy((OCPayload*)cstart);
282         OICFree(cborData);
283
284         OC::MessageContainer mc2;
285         mc2.setPayload(cparsed);
286         EXPECT_EQ(1u, mc2.representations().size());
287         const OC::OCRepresentation& r = mc2.representations()[0];
288
289         EXPECT_TRUE(r.isNULL("NullAttr"));
290         EXPECT_EQ(77, r.getValue<int>("IntAttr"));
291         EXPECT_EQ(3.333, r.getValue<double>("DoubleAttr"));
292         EXPECT_EQ(true, r.getValue<bool>("BoolAttr"));
293         EXPECT_STREQ("String attr", r.getValue<std::string>("StringAttr").c_str());
294         const char *expectedByteString = "\\x1\\x2\\x3\\x4\\x5\\x6\\x7\\x8\\x9\\x0\\xa\\xb\\xc\\xd\\xe\\xf";
295         EXPECT_STREQ(expectedByteString, r.getValueToString("ByteStringAttr").c_str());
296
297         OCPayloadDestroy(cparsed);
298     }
299
300     TEST(RepresentationEncoding, RepAttributeEmpty)
301     {
302         OC::OCRepresentation startRep;
303         std::vector<int> iarr {};
304         startRep["iarr"] = {};
305
306         OC::MessageContainer mc1;
307         mc1.addRepresentation(startRep);
308
309         OCRepPayload* cstart = mc1.getPayload();
310         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
311
312         uint8_t *cborData = NULL;
313         size_t cborSize = 0;
314         OCPayload *cparsed = NULL;
315         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
316         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
317                     cborData, cborSize));
318         OCPayloadDestroy((OCPayload*)cstart);
319         OICFree(cborData);
320
321         OC::MessageContainer mc2;
322         mc2.setPayload(cparsed);
323         EXPECT_EQ(1u, mc2.representations().size());
324         const OC::OCRepresentation& r = mc2.representations()[0];
325
326         std::vector<int> iarr2 = r["iarr"];
327
328         EXPECT_EQ(iarr, iarr2);
329         OCPayloadDestroy(cparsed);
330     }
331
332     TEST(RepresentationEncoding, RepAttribute)
333     {
334         OC::OCRepresentation startRep;
335         OC::OCRepresentation subRep;
336         subRep.setNULL("NullAttr");
337         subRep.setValue("IntAttr", 77);
338         subRep.setValue("DoubleAttr", 3.333);
339         subRep.setValue("BoolAttr", true);
340         subRep.setValue("StringAttr", std::string("String attr"));
341         std::vector<uint8_t> bin_data {5,3,4,5,6,0,34,2,4,5,6,3};
342         subRep.setValue("BinaryAttr", bin_data);
343         startRep.setValue("Sub", subRep);
344
345         OC::MessageContainer mc1;
346         mc1.addRepresentation(startRep);
347
348         OCRepPayload* cstart = mc1.getPayload();
349         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
350
351         uint8_t* cborData;
352         size_t cborSize;
353         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
354         OCPayload* cparsed;
355         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
356                     cborData, cborSize));
357         OCPayloadDestroy((OCPayload*)cstart);
358         OICFree(cborData);
359
360         OC::MessageContainer mc2;
361         mc2.setPayload(cparsed);
362         EXPECT_EQ(1u, mc2.representations().size());
363         const OC::OCRepresentation& r = mc2.representations()[0];
364
365         OC::OCRepresentation newSubRep = r["Sub"];
366
367         EXPECT_TRUE(newSubRep.isNULL("NullAttr"));
368         EXPECT_EQ(77, newSubRep.getValue<int>("IntAttr"));
369         EXPECT_EQ(3.333, newSubRep.getValue<double>("DoubleAttr"));
370         EXPECT_EQ(true, newSubRep.getValue<bool>("BoolAttr"));
371         EXPECT_STREQ("String attr", newSubRep.getValue<std::string>("StringAttr").c_str());
372         EXPECT_EQ(bin_data,
373                 newSubRep.getValue<std::vector<uint8_t>>("BinaryAttr"));
374         OCPayloadDestroy(cparsed);
375     }
376
377     TEST(RepresentationEncoding, OneDVectors)
378     {
379         // Setup
380         OC::OCRepresentation startRep;
381
382         OC::OCRepresentation subRep1;
383         OC::OCRepresentation subRep2;
384         OC::OCRepresentation subRep3;
385         subRep1.setNULL("NullAttr");
386         subRep1.setValue("IntAttr", 77);
387         subRep2.setValue("DoubleAttr", 3.333);
388         subRep2.setValue("BoolAttr", true);
389         subRep3.setValue("StringAttr", std::string("String attr"));
390
391         std::vector<int> iarr {1,2,3,4,5,6,7,8,9};
392         std::vector<double> darr {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
393         std::vector<bool> barr {false, true, false, false, true, true};
394         std::vector<std::string> strarr {"item1", "item2", "item3", "item4"};
395         std::vector<OC::OCRepresentation> objarr {subRep1, subRep2, subRep3};
396
397         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
398         OCByteString byteStringRef1 {binval1, sizeof(binval1)};
399         OCByteString byteString1 {NULL,0};
400         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
401         uint8_t binval2[] = {0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
402         OCByteString byteStringRef2 {binval2, sizeof(binval2)};
403         OCByteString byteString2 {NULL,0};
404         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
405         std::vector<OCByteString> bytestrarrRef {byteStringRef1, byteStringRef2 };
406         std::vector<OCByteString> bytestrarr {byteString1, byteString2 };
407
408         startRep["iarr"] = iarr;
409         startRep["darr"] = darr;
410         startRep["barr"] = barr;
411         startRep["strarr"] = strarr;
412         startRep["objarr"] = objarr;
413         startRep["bytestrarr"] = bytestrarr;
414
415         // Encode/decode
416         OC::MessageContainer mc1;
417         mc1.addRepresentation(startRep);
418
419         OCRepPayload* cstart = mc1.getPayload();
420         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
421
422         uint8_t* cborData;
423         size_t cborSize;
424         OCPayload* cparsed;
425         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
426         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
427                                               cborData, cborSize));
428         OCPayloadDestroy((OCPayload *)cstart);
429         OICFree(cborData);
430
431         OC::MessageContainer mc2;
432         mc2.setPayload(cparsed);
433         EXPECT_EQ(1u, mc2.representations().size());
434         const OC::OCRepresentation &r = mc2.representations()[0];
435
436         // Test
437         std::vector<int> iarr2 = r["iarr"];
438         std::vector<double> darr2 = r["darr"];
439         std::vector<bool> barr2 = r["barr"];
440         std::vector<std::string> strarr2 = r["strarr"];
441         std::vector<OC::OCRepresentation> objarr2 = r["objarr"];
442         std::vector<OCByteString> bytestrarr2 = r["bytestrarr"];
443
444         EXPECT_EQ(iarr, iarr2);
445         EXPECT_EQ(darr, darr2);
446         EXPECT_EQ(barr, barr2);
447         EXPECT_EQ(strarr, strarr2);
448         EXPECT_EQ(objarr, objarr2);
449
450         EXPECT_EQ(bytestrarrRef, bytestrarr2);
451         OCPayloadDestroy(cparsed);
452     }
453
454     TEST(RepresentationEncoding, TwoDVectors)
455     {
456         // Setup
457         OC::OCRepresentation startRep;
458
459         OC::OCRepresentation subRep1;
460         OC::OCRepresentation subRep2;
461         OC::OCRepresentation subRep3;
462         subRep1.setNULL("NullAttr");
463         subRep1.setValue("IntAttr", 77);
464         subRep2.setValue("DoubleAttr", 3.333);
465         subRep2.setValue("BoolAttr", true);
466         subRep3.setValue("StringAttr", std::string("String attr"));
467
468         std::vector<std::vector<int>> iarr {{1,2,3},{4,5,6},{7,8,9}};
469         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{7.7,8.8,9.9}};
470         std::vector<std::vector<bool>> barr {{false, true}, {false, false}, {true, true}};
471         std::vector<std::vector<std::string>> strarr {{"item1", "item2"}, {"item3", "item4"}};
472         std::vector<std::vector<OC::OCRepresentation>> objarr
473         {{subRep1, subRep2, subRep3}, {subRep3, subRep2, subRep1}};
474
475         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4};
476         OCByteString byteStringRef1 {binval1, sizeof(binval1) };
477         OCByteString byteString1 {NULL,0};
478         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
479         uint8_t binval2[] = {0x5, 0x6, 0x7, 0x8};
480         OCByteString byteStringRef2 {binval2, sizeof(binval2) };
481         OCByteString byteString2 {NULL,0};
482         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
483         uint8_t binval3[] = {0x9, 0x0, 0xA, 0xB};
484         OCByteString byteStringRef3 {binval3, sizeof(binval3) };
485         OCByteString byteString3 {NULL,0};
486         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
487         uint8_t binval4[] = {0xC, 0xD, 0xE, 0xF};
488         OCByteString byteStringRef4 {binval4, sizeof(binval4) };
489         OCByteString byteString4 {NULL,0};
490         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
491         std::vector<std::vector<OCByteString>> bytestrarrRef
492         {
493             {byteStringRef1, byteStringRef2}, {byteStringRef3, byteStringRef4}
494         };
495         std::vector<std::vector<OCByteString>> bytestrarr
496         {
497             {byteString1, byteString2}, {byteString3, byteString4}
498         };
499
500         startRep["iarr"] = iarr;
501         startRep["darr"] = darr;
502         startRep["barr"] = barr;
503         startRep["strarr"] = strarr;
504         startRep["objarr"] = objarr;
505         startRep["bytestrarr"] = bytestrarr;
506
507         // Encode/decode
508         OC::MessageContainer mc1;
509         mc1.addRepresentation(startRep);
510
511         OCRepPayload *cstart = mc1.getPayload();
512         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
513
514         uint8_t* cborData;
515         size_t cborSize;
516         OCPayload* cparsed;
517         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
518         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
519                                               cborData, cborSize));
520         OCPayloadDestroy((OCPayload *)cstart);
521         OICFree(cborData);
522
523         OC::MessageContainer mc2;
524         mc2.setPayload(cparsed);
525         EXPECT_EQ(1u, mc2.representations().size());
526         const OC::OCRepresentation &r = mc2.representations()[0];
527
528         // Test
529         std::vector<std::vector<int>> iarr2 = r["iarr"];
530         std::vector<std::vector<double>> darr2 = r["darr"];
531         std::vector<std::vector<bool>> barr2 = r["barr"];
532         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
533         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
534         std::vector<std::vector<OCByteString>> bytestrarr2 = r["bytestrarr"];
535
536         EXPECT_EQ(iarr, iarr2);
537         EXPECT_EQ(darr, darr2);
538         EXPECT_EQ(barr, barr2);
539         EXPECT_EQ(strarr, strarr2);
540         EXPECT_EQ(objarr, objarr2);
541
542         EXPECT_EQ(bytestrarrRef, bytestrarr2);
543
544         OCPayloadDestroy(cparsed);
545     }
546
547     TEST(RepresentationEncoding, TwoDVectorsJagged)
548     {
549         // Setup
550         OC::OCRepresentation startRep;
551
552         OC::OCRepresentation subRep1;
553         OC::OCRepresentation subRep2;
554         OC::OCRepresentation subRep3;
555         subRep1.setNULL("NullAttr");
556         subRep1.setValue("IntAttr", 77);
557         subRep2.setValue("DoubleAttr", 3.333);
558         subRep2.setValue("BoolAttr", true);
559         subRep3.setValue("StringAttr", std::string("String attr"));
560
561         std::vector<std::vector<int>> iarr {{1,2,3},{4,6},{7,8,9}};
562         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{8.8,9.9}};
563         std::vector<std::vector<bool>> barr {{false, true}, {false}, {true, true}};
564         std::vector<std::vector<std::string>> strarr {{"item1"}, {"item3", "item4"}};
565         std::vector<std::vector<OC::OCRepresentation>> objarr
566         {{subRep1, subRep3}, {subRep3, subRep2, subRep1}};
567
568         uint8_t binval1[] = {0x1};
569         OCByteString byteStringRef1 {binval1, sizeof(binval1) };
570         OCByteString byteString1 {NULL,0};
571         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
572         uint8_t binval3[] = {0x2, 0x3, 0x4};
573         OCByteString byteStringRef3 {binval3, sizeof(binval3) };
574         OCByteString byteString3 {NULL,0};
575         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
576         uint8_t binval4[] = {0x5, 0x6, 0x7, 0x8};
577         OCByteString byteStringRef4 {binval4, sizeof(binval4) };
578         OCByteString byteString4 {NULL,0};
579         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
580
581         std::vector<std::vector<OCByteString>> bytestrarrRef
582         {
583             {byteStringRef1}, {byteStringRef3, byteStringRef4}
584         };
585
586         std::vector<std::vector<OCByteString>> bytestrarr
587         {
588             {byteString1}, {byteString3, byteString4}
589         };
590
591         startRep["iarr"] = iarr;
592         startRep["darr"] = darr;
593         startRep["barr"] = barr;
594         startRep["strarr"] = strarr;
595         startRep["objarr"] = objarr;
596
597         startRep["bytestrarr"] = bytestrarr;
598
599         EXPECT_STREQ("[[\\x1 ] [\\x2\\x3\\x4 \\x5\\x6\\x7\\x8 ] ]",
600                      startRep.getValueToString("bytestrarr").c_str());
601         // Encode/decode
602         OC::MessageContainer mc1;
603         mc1.addRepresentation(startRep);
604
605         OCRepPayload *cstart = mc1.getPayload();
606         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
607
608         uint8_t *cborData;
609         size_t cborSize;
610         OCPayload *cparsed;
611         OCStackResult result = OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize);
612         EXPECT_EQ(OC_STACK_OK, result);
613         result = OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
614                                 cborData, cborSize);
615         EXPECT_EQ(OC_STACK_OK, result);
616
617         OCPayloadDestroy((OCPayload *)cstart);
618         OICFree(cborData);
619
620         OC::MessageContainer mc2;
621         mc2.setPayload(cparsed);
622         EXPECT_EQ(1u, mc2.representations().size());
623         const OC::OCRepresentation &r = mc2.representations()[0];
624
625         // Test
626         std::vector<std::vector<int>> iarr2 = r["iarr"];
627         std::vector<std::vector<double>> darr2 = r["darr"];
628         std::vector<std::vector<bool>> barr2 = r["barr"];
629         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
630         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
631
632         std::vector<std::vector<OCByteString>> bytestrarr2 = r["bytestrarr"];
633
634         // Note: due to the way that the CSDK works, all 2d arrays need to be rectangular.
635         // Since std::vector doesn't require this, items received on the other side end up
636         // being backfilled.  This section removes the backfilling
637         iarr2[1].pop_back();
638         darr2[2].pop_back();
639         barr2[1].pop_back();
640         strarr2[0].pop_back();
641         objarr2[0].pop_back();
642         bytestrarr2[0].pop_back();
643
644         EXPECT_EQ(iarr, iarr2);
645         EXPECT_EQ(darr, darr2);
646         EXPECT_EQ(barr, barr2);
647         EXPECT_EQ(strarr, strarr2);
648         EXPECT_EQ(objarr, objarr2);
649         EXPECT_EQ(bytestrarr.size(), bytestrarr2.size());
650         EXPECT_EQ(bytestrarrRef, bytestrarr2);
651
652         OCPayloadDestroy(cparsed);
653     }
654
655     TEST(RepresentationEncoding, ThreeDVectors)
656     {
657         // Setup
658         OC::OCRepresentation startRep;
659
660         OC::OCRepresentation subRep1;
661         OC::OCRepresentation subRep2;
662         OC::OCRepresentation subRep3;
663         subRep1.setNULL("NullAttr");
664         subRep1.setValue("IntAttr", 77);
665         subRep2.setValue("DoubleAttr", 3.333);
666         subRep2.setValue("BoolAttr", true);
667         subRep3.setValue("StringAttr", std::string("String attr"));
668
669         std::vector<std::vector<std::vector<int>>> iarr
670             {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}},{{13,14,15},{16,17,18}}};
671         std::vector<std::vector<std::vector<double>>> darr
672             {{{1.1,2.2,3.3},{4.4,5.5,6.6}},
673                 {{7.7,8.7,9.7},{10.7,11.7,12.7}},
674                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}};
675         std::vector<std::vector<std::vector<bool>>> barr
676             {{{false, true},{true, false}},{{false, true},{true, false}}};
677         std::vector<std::vector<std::vector<std::string>>> strarr
678             {
679                 {{"item1", "item2"},{"item3", "item4"}},
680                 {{"item5", "item6"},{"item7", "item8"}},
681                 {{"item9", "item10"},{"item11", ""}}
682             };
683         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
684             {
685                 {{subRep1, subRep2},{subRep3, subRep1}},
686                 {{subRep2, subRep3},{subRep2, subRep1}},
687                 {{subRep3, subRep2},{subRep1, subRep2}}
688             };
689
690         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4};
691         OCByteString byteStringRef1 {binval1, sizeof(binval1)};
692         OCByteString byteString1 {NULL,0};
693         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
694         uint8_t binval2[] = {0x5, 0x6, 0x7, 0x8};
695         OCByteString byteStringRef2 {binval2, sizeof(binval2)};
696         OCByteString byteString2 {NULL,0};
697         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
698         uint8_t binval3[] = {0x9, 0x0, 0xA, 0xB};
699         OCByteString byteStringRef3 {binval3, sizeof(binval3)};
700         OCByteString byteString3 {NULL,0};
701         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
702         uint8_t binval4[] = {0xC, 0xD, 0xE, 0xF};
703         OCByteString byteStringRef4 {binval4, sizeof(binval4)};
704         OCByteString byteString4 {NULL,0};
705         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
706         uint8_t binval5[] = {0x11, 0x12, 0x13, 0x14};
707         OCByteString byteStringRef5 {binval5, sizeof(binval5)};
708         OCByteString byteString5 {NULL,0};
709         EXPECT_TRUE(OCByteStringCopy(&byteString5, &byteStringRef5));
710         uint8_t binval6[] = {0x15, 0x16, 0x17, 0x18};
711         OCByteString byteStringRef6 {binval6, sizeof(binval6)};
712         OCByteString byteString6 {NULL,0};
713         EXPECT_TRUE(OCByteStringCopy(&byteString6, &byteStringRef6));
714         uint8_t binval7[] = {0x19, 0x10, 0x1A, 0x1B};
715         OCByteString byteStringRef7 {binval7, sizeof(binval7)};
716         OCByteString byteString7 {NULL,0};
717         EXPECT_TRUE(OCByteStringCopy(&byteString7, &byteStringRef7));
718         uint8_t binval8[] = {0x1C, 0x1D, 0x1E, 0x1F};
719         OCByteString byteStringRef8 {binval8, sizeof(binval8)};
720         OCByteString byteString8 {NULL,0};
721         EXPECT_TRUE(OCByteStringCopy(&byteString8, &byteStringRef8));
722         uint8_t binval9[] = {0x21, 0x22, 0x23, 0x24};
723         OCByteString byteStringRef9 {binval9, sizeof(binval9)};
724         OCByteString byteString9 {NULL,0};
725         EXPECT_TRUE(OCByteStringCopy(&byteString9, &byteStringRef9));
726         uint8_t binval10[] = {0x25, 0x26, 0x27, 0x28};
727         OCByteString byteStringRef10 {binval10, sizeof(binval10)};
728         OCByteString byteString10 {NULL,0};
729         EXPECT_TRUE(OCByteStringCopy(&byteString10, &byteStringRef10));
730         uint8_t binval11[] = {0x29, 0x20, 0x2A, 0x2B};
731         OCByteString byteStringRef11 {binval11, sizeof(binval11)};
732         OCByteString byteString11 {NULL,0};
733         EXPECT_TRUE(OCByteStringCopy(&byteString11, &byteStringRef11));
734         uint8_t binval12[] = {0xFF};
735         OCByteString byteStringRef12 {binval12, sizeof(binval12)};
736         OCByteString byteString12 {NULL,0};
737         EXPECT_TRUE(OCByteStringCopy(&byteString12, &byteStringRef12));
738
739         std::vector<std::vector<std::vector<OCByteString>>> bytestrarrRef
740         {
741             {{byteStringRef1, byteStringRef2}, {byteStringRef3, byteStringRef4}},
742             {{byteStringRef5, byteStringRef6}, {byteStringRef7, byteStringRef8}},
743             {{byteStringRef9, byteStringRef10}, {byteStringRef11, byteStringRef12}}
744         };
745
746         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr
747         {
748             {{byteString1, byteString2}, {byteString3, byteString4}},
749             {{byteString5, byteString6}, {byteString7, byteString8}},
750             {{byteString9, byteString10}, {byteString11, byteString12}}
751         };
752
753         startRep["iarr"] = iarr;
754         startRep["darr"] = darr;
755         startRep["barr"] = barr;
756         startRep["strarr"] = strarr;
757         startRep["objarr"] = objarr;
758         startRep["bytestrarr"] = bytestrarr;
759
760         // Encode/decode
761         OC::MessageContainer mc1;
762         mc1.addRepresentation(startRep);
763
764         OCRepPayload *cstart = mc1.getPayload();
765         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
766
767         uint8_t *cborData;
768         size_t cborSize;
769         OCPayload *cparsed;
770         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
771         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
772                                               cborData, cborSize));
773         OCPayloadDestroy((OCPayload *)cstart);
774         OICFree(cborData);
775
776         OC::MessageContainer mc2;
777         mc2.setPayload(cparsed);
778         EXPECT_EQ(1u, mc2.representations().size());
779         const OC::OCRepresentation &r = mc2.representations()[0];
780
781         // Test
782         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
783         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
784         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
785         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
786         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
787         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr2 = r["bytestrarr"];
788
789         EXPECT_EQ(iarr, iarr2);
790         EXPECT_EQ(darr, darr2);
791         EXPECT_EQ(barr, barr2);
792         EXPECT_EQ(strarr, strarr2);
793         EXPECT_EQ(objarr, objarr2);
794         EXPECT_EQ(bytestrarrRef, bytestrarr2);
795         OCPayloadDestroy(cparsed);
796     }
797
798     TEST(RepresentationEncoding, ThreeDVectorsJagged)
799     {
800         // Setup
801         OC::OCRepresentation startRep;
802
803         OC::OCRepresentation subRep1;
804         OC::OCRepresentation subRep2;
805         OC::OCRepresentation subRep3;
806         subRep1.setNULL("NullAttr");
807         subRep1.setValue("IntAttr", 77);
808         subRep2.setValue("DoubleAttr", 3.333);
809         subRep2.setValue("BoolAttr", true);
810         subRep3.setValue("StringAttr", std::string("String attr"));
811
812         std::vector<std::vector<std::vector<int>>> iarr
813             {
814                 {{1,2,3},{4,5,6}},
815                 {{7,8,9},{10,12}},
816                 {{13,14,15},{16,17,18}}
817             };
818         std::vector<std::vector<std::vector<double>>> darr
819             {
820                 {{1.1,2.2,3.3},{4.4,5.5,6.6}},
821                 {{7.7,8.7,9.7},{10.7,12.7}},
822                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}
823             };
824         std::vector<std::vector<std::vector<bool>>> barr
825             {
826                 {{false, true},{true}},
827                 {{false, true},{true, false}}
828             };
829         std::vector<std::vector<std::vector<std::string>>> strarr
830             {
831                 {{"item1", "item2"},{"item3", "item4"}},
832                 {{"item5", "item6"},{"item8"}},
833                 {{"item9", "item10"},{"item11", ""}}
834             };
835         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
836             {
837                 {{subRep1, subRep2},{subRep3, subRep1}},
838                 {{subRep2, subRep3},{subRep2}},
839                 {{subRep3, subRep2}}
840             };
841
842         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4};
843         OCByteString byteStringRef1 {binval1, sizeof(binval1)};
844         OCByteString byteString1 {NULL,0};
845         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
846         uint8_t binval2[] = {0x5, 0x6, 0x7, 0x8};
847         OCByteString byteStringRef2 {binval2, sizeof(binval2)};
848         OCByteString byteString2 {NULL,0};
849         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
850         uint8_t binval3[] = {0x9, 0x0, 0xA, 0xB};
851         OCByteString byteStringRef3 {binval3, sizeof(binval3)};
852         OCByteString byteString3 {NULL,0};
853         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
854         uint8_t binval4[] = {0xC, 0xD, 0xE, 0xF};
855         OCByteString byteStringRef4 {binval4, sizeof(binval4)};
856         OCByteString byteString4 {NULL,0};
857         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
858         uint8_t binval5[] = {0x11, 0x12, 0x13, 0x14};
859         OCByteString byteStringRef5 {binval5, sizeof(binval5)};
860         OCByteString byteString5 {NULL,0};
861         EXPECT_TRUE(OCByteStringCopy(&byteString5, &byteStringRef5));
862         uint8_t binval6[] = {0x15, 0x16, 0x17, 0x18};
863         OCByteString byteStringRef6 {binval6, sizeof(binval6)};
864         OCByteString byteString6 {NULL,0};
865         EXPECT_TRUE(OCByteStringCopy(&byteString6, &byteStringRef6));
866         uint8_t binval8[] = {0x1C, 0x1D, 0x1E, 0x1F};
867         OCByteString byteStringRef8 {binval8, sizeof(binval8)};
868         OCByteString byteString8 {NULL,0};
869         EXPECT_TRUE(OCByteStringCopy(&byteString8, &byteStringRef8));
870         uint8_t binval9[] = {0x21, 0x22, 0x23, 0x24};
871         OCByteString byteStringRef9 {binval9, sizeof(binval9)};
872         OCByteString byteString9 {NULL,0};
873         EXPECT_TRUE(OCByteStringCopy(&byteString9, &byteStringRef9));
874         uint8_t binval10[] = {0x25, 0x26, 0x27, 0x28};
875         OCByteString byteStringRef10 {binval10, sizeof(binval10)};
876         OCByteString byteString10 {NULL,0};
877         EXPECT_TRUE(OCByteStringCopy(&byteString10, &byteStringRef10));
878         uint8_t binval11[] = {0x29, 0x20, 0x2A, 0x2B};
879         OCByteString byteStringRef11 {binval11, sizeof(binval11)};
880         OCByteString byteString11 {NULL,0};
881         EXPECT_TRUE(OCByteStringCopy(&byteString11, &byteStringRef11));
882         uint8_t binval12[] = {0xFF};
883         OCByteString byteStringRef12 {binval12, sizeof(binval12)};
884         OCByteString byteString12 {NULL,0};
885         EXPECT_TRUE(OCByteStringCopy(&byteString12, &byteStringRef12));
886
887         std::vector<std::vector<std::vector<OCByteString>>> bytestrarrRef
888         {
889             {{byteStringRef1, byteStringRef2}, {byteStringRef3, byteStringRef4}},
890             {{byteStringRef5, byteStringRef6}, {byteStringRef8}},
891             {{byteStringRef9, byteStringRef10}, {byteStringRef11, byteStringRef12}}
892         };
893
894         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr
895         {
896             {{byteString1, byteString2}, {byteString3, byteString4}},
897             {{byteString5, byteString6}, {byteString8}},
898             {{byteString9, byteString10}, {byteString11, byteString12}}
899         };
900
901         startRep["iarr"] = iarr;
902         startRep["darr"] = darr;
903         startRep["barr"] = barr;
904         startRep["strarr"] = strarr;
905         startRep["objarr"] = objarr;
906         startRep["bytestrarr"] = bytestrarr;
907
908         // Encode/decode
909         OC::MessageContainer mc1;
910         mc1.addRepresentation(startRep);
911
912         OCRepPayload *cstart = mc1.getPayload();
913         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
914
915         uint8_t *cborData;
916         size_t cborSize;
917         OCPayload *cparsed;
918         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
919         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
920                                               cborData, cborSize));
921         OCPayloadDestroy((OCPayload *)cstart);
922         OICFree(cborData);
923
924         OC::MessageContainer mc2;
925         mc2.setPayload(cparsed);
926         EXPECT_EQ(1u, mc2.representations().size());
927         const OC::OCRepresentation &r = mc2.representations()[0];
928
929         // Test
930         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
931         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
932         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
933         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
934         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
935         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr2 = r["bytestrarr"];
936
937         // Note: due to the way that the CSDK works, all 3d arrays need to be cuboidal.
938         // Since std::vector doesn't require this, items received on the other side end up
939         // being backfilled.  This section removes the backfilling
940         iarr2[1][1].pop_back();
941         darr2[1][1].pop_back();
942         barr2[0][1].pop_back();
943         strarr2[1][1].pop_back();
944         objarr2[1][1].pop_back();
945         objarr2[2].pop_back();
946         bytestrarr2[1][1].pop_back();
947
948         EXPECT_EQ(iarr, iarr2);
949         EXPECT_EQ(darr, darr2);
950         EXPECT_EQ(barr, barr2);
951         EXPECT_EQ(strarr, strarr2);
952         EXPECT_EQ(objarr, objarr2);
953         EXPECT_EQ(bytestrarrRef, bytestrarr2);
954         OCPayloadDestroy(cparsed);
955     }
956
957     TEST(DiscoveryRTandIF, SingleItemNormal)
958     {
959         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
960         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
961         payload->sid = OICStrdup(sid1);
962         payload->resources = resource;
963
964         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem"));
965         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem"));
966
967         resource->uri = OICStrdup("/uri/thing");
968
969         uint8_t* cborData;
970         size_t cborSize;
971         OCPayload* cparsed;
972
973         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
974         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
975                     cborData, cborSize));
976
977         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
978         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
979
980         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
981         EXPECT_EQ(NULL, parsedResource->next);
982         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
983         EXPECT_EQ(NULL, parsedResource->types->next);
984         EXPECT_EQ(NULL, parsedResource->interfaces->next);
985         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
986
987         OICFree(cborData);
988         OCPayloadDestroy(cparsed);
989         OCDiscoveryPayloadDestroy(payload);
990     }
991
992     TEST(DiscoveryRTandIF, SingleItemFrontTrim)
993     {
994         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
995         payload->sid = OICStrdup(sid1);
996         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
997         payload->resources = resource;
998
999         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem"));
1000         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem"));
1001         resource->uri = OICStrdup("/uri/thing");
1002
1003         uint8_t* cborData;
1004         size_t cborSize;
1005         OCPayload* cparsed;
1006
1007         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1008         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1009                     cborData, cborSize));
1010
1011         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1012         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1013
1014         EXPECT_EQ(NULL, parsedResource->next);
1015         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1016         EXPECT_EQ(NULL, parsedResource->types->next);
1017         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1018         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1019         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1020
1021         OICFree(cborData);
1022         OCPayloadDestroy(cparsed);
1023         OCDiscoveryPayloadDestroy(payload);
1024     }
1025
1026     TEST(DiscoveryRTandIF, SingleItemBackTrim)
1027     {
1028         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1029         payload->sid = OICStrdup(sid1);
1030         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1031         payload->resources = resource;
1032
1033         OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem    ");
1034         OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem    ");
1035         resource->uri = OICStrdup("/uri/thing");
1036
1037         uint8_t* cborData;
1038         size_t cborSize;
1039         OCPayload* cparsed;
1040
1041         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1042         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1043                     cborData, cborSize));
1044
1045         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1046         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1047
1048         EXPECT_EQ(NULL, parsedResource->next);
1049         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1050         EXPECT_EQ(NULL, parsedResource->types->next);
1051         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1052         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1053         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1054
1055         OICFree(cborData);
1056         OCPayloadDestroy(cparsed);
1057         OCDiscoveryPayloadDestroy(payload);
1058     }
1059     TEST(DiscoveryRTandIF, SingleItemBothTrim)
1060     {
1061         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1062         payload->sid = OICStrdup(sid1);
1063         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1064         payload->resources = resource;
1065
1066         OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem    ");
1067         OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem     ");
1068         resource->uri = OICStrdup("/uri/thing");
1069
1070         uint8_t* cborData;
1071         size_t cborSize;
1072         OCPayload* cparsed;
1073
1074         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1075         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1076                     cborData, cborSize));
1077
1078         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1079         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1080
1081         EXPECT_EQ(NULL, parsedResource->next);
1082         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1083         EXPECT_EQ(NULL, parsedResource->types->next);
1084         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1085         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1086         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1087
1088         OICFree(cborData);
1089         OCPayloadDestroy(cparsed);
1090         OCDiscoveryPayloadDestroy(payload);
1091     }
1092     TEST(DiscoveryRTandIF, MultiItemsNormal)
1093     {
1094         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1095         payload->sid = OICStrdup(sid1);
1096         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1097         payload->resources = resource;
1098
1099         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem");
1100         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem");
1101         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem");
1102         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem");
1103         resource->uri = OICStrdup("/uri/thing");
1104
1105         uint8_t* cborData;
1106         size_t cborSize;
1107         OCPayload* cparsed;
1108
1109         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1110         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1111                     cborData, cborSize));
1112
1113         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1114         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1115
1116         EXPECT_EQ(NULL, parsedResource->next);
1117         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1118         EXPECT_EQ(NULL, parsedResource->types->next->next);
1119         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1120         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1121         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1122         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1123         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1124
1125         OICFree(cborData);
1126         OCPayloadDestroy(cparsed);
1127         OCDiscoveryPayloadDestroy(payload);
1128     }
1129     TEST(DiscoveryRTandIF, MultiItemExtraLeadSpaces)
1130     {
1131         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1132         payload->sid = OICStrdup(sid1);
1133         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1134         payload->resources = resource;
1135
1136         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem");
1137         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem");
1138         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem");
1139         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem");
1140         resource->uri = OICStrdup("/uri/thing");
1141
1142         uint8_t* cborData;
1143         size_t cborSize;
1144         OCPayload* cparsed;
1145
1146         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1147         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1148                     cborData, cborSize));
1149
1150         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1151         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1152
1153         EXPECT_EQ(NULL, parsedResource->next);
1154         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1155         EXPECT_EQ(NULL, parsedResource->types->next->next);
1156         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1157         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1158         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1159         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1160         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1161
1162         OICFree(cborData);
1163         OCPayloadDestroy(cparsed);
1164         OCDiscoveryPayloadDestroy(payload);
1165     }
1166     TEST(DiscoveryRTandIF, MultiItemExtraTrailSpaces)
1167     {
1168         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1169         payload->sid = OICStrdup(sid1);
1170         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1171         payload->resources = resource;
1172
1173         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem  ");
1174         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem  ");
1175         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem  ");
1176         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem  ");
1177         resource->uri = OICStrdup("/uri/thing");
1178
1179         uint8_t* cborData;
1180         size_t cborSize;
1181         OCPayload* cparsed;
1182
1183         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1184         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1185                     cborData, cborSize));
1186
1187         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1188         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1189
1190         EXPECT_EQ(NULL, parsedResource->next);
1191         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1192         EXPECT_EQ(NULL, parsedResource->types->next->next);
1193         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1194         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1195         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1196         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1197         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1198
1199         OICFree(cborData);
1200         OCPayloadDestroy(cparsed);
1201         OCDiscoveryPayloadDestroy(payload);
1202     }
1203     TEST(DiscoveryRTandIF, MultiItemBothSpaces)
1204     {
1205         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1206         payload->sid = OICStrdup(sid1);
1207         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1208         payload->resources = resource;
1209
1210         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem  ");
1211         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem  ");
1212         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem  ");
1213         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem  ");
1214         resource->uri = OICStrdup("/uri/thing");
1215
1216         uint8_t* cborData;
1217         size_t cborSize;
1218         OCPayload* cparsed;
1219
1220         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1221         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1222                     cborData, cborSize));
1223
1224         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1225         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1226
1227         EXPECT_EQ(NULL, parsedResource->next);
1228         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1229         EXPECT_EQ(NULL, parsedResource->types->next->next);
1230         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1231         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1232         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1233         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1234         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1235
1236         OICFree(cborData);
1237         OCPayloadDestroy(cparsed);
1238         OCDiscoveryPayloadDestroy(payload);
1239     }
1240     TEST(RepresentationEncodingRTandIF, SingleItemNormal)
1241     {
1242         OCRepPayload* payload = OCRepPayloadCreate();
1243         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1244         OCRepPayloadAddInterface(payload, "if.firstitem");
1245
1246         uint8_t* cborData;
1247         size_t cborSize;
1248         OCPayload* cparsed;
1249
1250         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1251         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1252                     cborData, cborSize));
1253
1254         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1255
1256         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1257         EXPECT_EQ(NULL, parsedPayload->types->next);
1258         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1259         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1260
1261         OICFree(cborData);
1262         OCRepPayloadDestroy(payload);
1263         OCPayloadDestroy(cparsed);
1264     }
1265     TEST(RepresentationEncodingRTandIF, SingleItemFrontTrim)
1266     {
1267         OCRepPayload* payload = OCRepPayloadCreate();
1268         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1269         OCRepPayloadAddInterface(payload, "  if.firstitem");
1270
1271         uint8_t* cborData;
1272         size_t cborSize;
1273         OCPayload* cparsed;
1274
1275         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1276         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1277                     cborData, cborSize));
1278
1279         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1280
1281         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1282         EXPECT_EQ(NULL, parsedPayload->types->next);
1283         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1284         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1285
1286
1287         OICFree(cborData);
1288         OCRepPayloadDestroy(payload);
1289         OCPayloadDestroy(cparsed);
1290     }
1291     TEST(RepresentationEncodingRTandIF, SingleItemBackTrim)
1292     {
1293         OCRepPayload* payload = OCRepPayloadCreate();
1294         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1295         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1296
1297         uint8_t* cborData;
1298         size_t cborSize;
1299         OCPayload* cparsed;
1300
1301         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1302         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1303                     cborData, cborSize));
1304
1305         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1306
1307         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1308         EXPECT_EQ(NULL, parsedPayload->types->next);
1309         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1310         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1311
1312
1313         OICFree(cborData);
1314         OCRepPayloadDestroy(payload);
1315         OCPayloadDestroy(cparsed);
1316     }
1317     TEST(RepresentationEncodingRTandIF, SingleItemBothTrim)
1318     {
1319         OCRepPayload* payload = OCRepPayloadCreate();
1320         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1321         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1322
1323         uint8_t* cborData;
1324         size_t cborSize;
1325         OCPayload* cparsed;
1326
1327         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1328         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1329                     cborData, cborSize));
1330
1331         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1332
1333         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1334         EXPECT_EQ(NULL, parsedPayload->types->next);
1335         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1336         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1337
1338
1339         OICFree(cborData);
1340         OCRepPayloadDestroy(payload);
1341         OCPayloadDestroy(cparsed);
1342     }
1343     TEST(RepresentationEncodingRTandIF, MultiItemsNormal)
1344     {
1345         OCRepPayload* payload = OCRepPayloadCreate();
1346         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1347         OCRepPayloadAddResourceType(payload, "rt.seconditem");
1348         OCRepPayloadAddInterface(payload, "if.firstitem");
1349         OCRepPayloadAddInterface(payload, "if.seconditem");
1350
1351         uint8_t* cborData;
1352         size_t cborSize;
1353         OCPayload* cparsed;
1354
1355         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1356         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1357                     cborData, cborSize));
1358
1359         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1360
1361         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1362         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1363         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1364         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1365         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1366         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1367
1368
1369         OICFree(cborData);
1370         OCRepPayloadDestroy(payload);
1371         OCPayloadDestroy(cparsed);
1372     }
1373     TEST(RepresentationEncodingRTandIF, MultiItemExtraLeadSpaces)
1374     {
1375         OCRepPayload* payload = OCRepPayloadCreate();
1376         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1377         OCRepPayloadAddResourceType(payload, "  rt.seconditem");
1378         OCRepPayloadAddInterface(payload, "  if.firstitem");
1379         OCRepPayloadAddInterface(payload, "  if.seconditem");
1380
1381         uint8_t* cborData;
1382         size_t cborSize;
1383         OCPayload* cparsed;
1384
1385         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1386         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1387                     cborData, cborSize));
1388
1389         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1390
1391         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1392         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1393         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1394         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1395         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1396         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1397
1398
1399         OICFree(cborData);
1400         OCRepPayloadDestroy(payload);
1401         OCPayloadDestroy(cparsed);
1402     }
1403     TEST(RepresentationEncodingRTandIF, MultiItemExtraTrailSpaces)
1404     {
1405         OCRepPayload* payload = OCRepPayloadCreate();
1406         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1407         OCRepPayloadAddResourceType(payload, "rt.seconditem  ");
1408         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1409         OCRepPayloadAddInterface(payload, "if.seconditem  ");
1410
1411         uint8_t* cborData;
1412         size_t cborSize;
1413         OCPayload* cparsed;
1414
1415         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1416         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1417                     cborData, cborSize));
1418
1419         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1420
1421         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1422         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1423         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1424         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1425         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1426         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1427
1428
1429         OICFree(cborData);
1430         OCRepPayloadDestroy(payload);
1431         OCPayloadDestroy(cparsed);
1432     }
1433     TEST(RepresentationEncodingRTandIF, MultiItemExtraMiddleSpaces)
1434     {
1435         OCRepPayload* payload = OCRepPayloadCreate();
1436         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1437         OCRepPayloadAddResourceType(payload, "  rt.seconditem  ");
1438         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1439         OCRepPayloadAddInterface(payload, "  if.seconditem  ");
1440
1441         uint8_t* cborData;
1442         size_t cborSize;
1443         OCPayload* cparsed;
1444
1445         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1446         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1447                     cborData, cborSize));
1448
1449         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1450
1451         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1452         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1453         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1454         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1455         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1456         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1457
1458
1459         OICFree(cborData);
1460         OCRepPayloadDestroy(payload);
1461         OCPayloadDestroy(cparsed);
1462     }
1463     TEST(RepresentationEncodingRTandIF, TestPayloadContents)
1464     {
1465         OC::OCRepresentation subRep1;
1466         std::vector<std::string> types;
1467         types.push_back("rt.firstitem");
1468         std::vector<std::string> interfaces;
1469         interfaces.push_back("if.firstitem");
1470         subRep1.setResourceTypes(types);
1471         subRep1.setResourceInterfaces(interfaces);
1472         subRep1.setNULL("NullAttr");
1473         subRep1.setValue("IntAttr", 77);
1474         subRep1.setValue("DoubleAttr", 3.333);
1475         subRep1.setValue("BoolAttr", true);
1476         subRep1.setValue("StringAttr", std::string("String attr"));
1477
1478         OC::MessageContainer mc1;
1479         mc1.addRepresentation(subRep1);
1480
1481         OCRepPayload *repPayload = mc1.getPayload();
1482         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, repPayload->base.type);
1483
1484         uint8_t *cborData = NULL;
1485         size_t cborSize = 0;
1486         OCPayload *cparsed = NULL;
1487
1488         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)repPayload, &cborData, &cborSize));
1489         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1490                     cborData, cborSize));
1491
1492         OCRepPayload *parsedPayload = (OCRepPayload *)cparsed;
1493         EXPECT_EQ(NULL, parsedPayload->uri);
1494         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1495         EXPECT_EQ(NULL, parsedPayload->types->next);
1496         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1497         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1498
1499         // To make sure rt and if are not duplicated.
1500         EXPECT_STREQ("BoolAttr", parsedPayload->values->name);
1501         EXPECT_EQ(true, parsedPayload->values->b);
1502         EXPECT_EQ(OCREP_PROP_BOOL, parsedPayload->values->type);
1503         parsedPayload->values = parsedPayload->values->next;
1504
1505         EXPECT_STREQ("DoubleAttr", parsedPayload->values->name);
1506         EXPECT_EQ(OCREP_PROP_DOUBLE, parsedPayload->values->type);
1507         EXPECT_EQ(3.3330000000000002, parsedPayload->values->d);
1508         parsedPayload->values = parsedPayload->values->next;
1509
1510         EXPECT_STREQ("IntAttr", parsedPayload->values->name);
1511         EXPECT_EQ(77, parsedPayload->values->i);
1512         EXPECT_EQ(OCREP_PROP_INT, parsedPayload->values->type);
1513         parsedPayload->values = parsedPayload->values->next;
1514
1515         EXPECT_STREQ("NullAttr", parsedPayload->values->name);
1516         EXPECT_EQ(OCREP_PROP_NULL, parsedPayload->values->type);
1517         parsedPayload->values = parsedPayload->values->next;
1518
1519         EXPECT_STREQ("StringAttr", parsedPayload->values->name);
1520         EXPECT_STREQ("String attr", parsedPayload->values->str);
1521         EXPECT_EQ(OCREP_PROP_STRING, parsedPayload->values->type);
1522         parsedPayload->values = parsedPayload->values->next;
1523
1524         EXPECT_EQ(NULL, parsedPayload->values);
1525
1526         OICFree(cborData);
1527         OCRepPayloadDestroy(repPayload);
1528         OCPayloadDestroy(cparsed);
1529     }
1530 }