Merge branch 'master' into extended-easysetup
[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 namespace OC
33 {
34     bool operator==(const OC::NullType&, const OC::NullType&)
35     {
36         return true;
37     }
38
39     bool operator==(const OC::OCRepresentation& lhs, const OC::OCRepresentation& rhs)
40     {
41         return lhs.getUri() == rhs.getUri() &&
42             lhs.getChildren() == rhs.getChildren() &&
43             lhs.getResourceInterfaces() == rhs.getResourceInterfaces() &&
44             lhs.getResourceTypes() == rhs.getResourceTypes() &&
45             lhs.m_values == rhs.m_values;
46     }
47 }
48 // these tests validate the OCRepresentation->OCPayload, OCPayload->CBOR,
49 // CBOR->OCPayload and OCPayload->OCRepresentation conversions
50 namespace OCRepresentationEncodingTest
51 {
52     static const char sid1[] = "646F6F72-4465-7669-6365-555549443030";
53     static const char devicename1[] = "device name";
54     static const char specver1[] = "spec version";
55     static const char dmver1[] = "res.1.1.0";
56     static OCStringLL *types = NULL;
57     // Device Payloads
58     TEST(DeviceDiscoveryEncoding, Normal)
59     {
60         OCResourcePayloadAddStringLL(&types, "oic.wk.d");
61         OCResourcePayloadAddStringLL(&types, "oic.d.tv");
62
63         OCDevicePayload* device = OCDevicePayloadCreate(
64                 sid1,
65                 devicename1,
66                 types,
67                 specver1,
68                 dmver1);
69         EXPECT_TRUE(device);
70         EXPECT_STREQ(sid1, device->sid);
71         EXPECT_STREQ(devicename1, device->deviceName);
72         EXPECT_STREQ(specver1, device->specVersion);
73         EXPECT_TRUE(device->dataModelVersions);
74         EXPECT_STREQ("res.1.1.0", device->dataModelVersions->value);
75         EXPECT_FALSE(device->dataModelVersions->next);
76         EXPECT_EQ(PAYLOAD_TYPE_DEVICE, ((OCPayload *)device)->type);
77         EXPECT_STREQ("oic.wk.d", device->types->value);
78         EXPECT_STREQ("oic.d.tv", device->types->next->value);
79
80         uint8_t* cborData;
81         size_t cborSize;
82         OCPayload* parsedDevice;
83         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)device, &cborData, &cborSize));
84         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedDevice, PAYLOAD_TYPE_DEVICE,
85                     cborData, cborSize));
86         OICFree(cborData);
87
88         EXPECT_STREQ(device->sid, ((OCDevicePayload*)parsedDevice)->sid);
89         EXPECT_STREQ(device->deviceName, ((OCDevicePayload*)parsedDevice)->deviceName);
90         EXPECT_STREQ(device->specVersion, ((OCDevicePayload*)parsedDevice)->specVersion);
91         EXPECT_STREQ(device->dataModelVersions->value, ((OCDevicePayload*)parsedDevice)->dataModelVersions->value);
92         EXPECT_STREQ("oic.wk.d", ((OCDevicePayload*)parsedDevice)->types->value);
93         EXPECT_STREQ("oic.d.tv", ((OCDevicePayload*)parsedDevice)->types->next->value);
94         EXPECT_EQ(device->base.type, ((OCDevicePayload*)parsedDevice)->base.type);
95
96         OCPayloadDestroy((OCPayload*)device);
97
98         OC::MessageContainer mc1;
99         mc1.setPayload(parsedDevice);
100         EXPECT_EQ(1u, mc1.representations().size());
101         const OC::OCRepresentation &r1 = mc1.representations()[0];
102         EXPECT_STREQ(sid1, r1.getValue<std::string>(OC_RSRVD_DEVICE_ID).c_str());
103         EXPECT_STREQ(devicename1, r1.getValue<std::string>(OC_RSRVD_DEVICE_NAME).c_str());
104         EXPECT_STREQ(specver1, r1.getValue<std::string>(OC_RSRVD_SPEC_VERSION).c_str());
105         EXPECT_STREQ("res.1.1.0", r1.getDataModelVersions()[0].c_str());
106
107         OCPayloadDestroy(parsedDevice);
108
109         static const char dmver2[] = "res.1.1.0,sh.1.1.0";
110         device = OCDevicePayloadCreate(
111                      sid1,
112                      devicename1,
113                      types,
114                      specver1,
115                      dmver2);
116
117         EXPECT_STREQ("res.1.1.0", device->dataModelVersions->value);
118         EXPECT_TRUE(device->dataModelVersions->next);
119         EXPECT_STREQ("sh.1.1.0", device->dataModelVersions->next->value);
120         EXPECT_FALSE(device->dataModelVersions->next->next);
121         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)device, &cborData, &cborSize));
122         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedDevice, PAYLOAD_TYPE_DEVICE,
123                                               cborData, cborSize));
124         OICFree(cborData);
125         EXPECT_STREQ(device->dataModelVersions->value,
126                      ((OCDevicePayload *)parsedDevice)->dataModelVersions->value);
127         EXPECT_STREQ(device->dataModelVersions->next->value,
128                      ((OCDevicePayload *)parsedDevice)->dataModelVersions->next->value);
129         OCPayloadDestroy((OCPayload *)device);
130         OC::MessageContainer mc2;
131         mc2.setPayload(parsedDevice);
132         EXPECT_EQ(1u, mc2.representations().size());
133         const OC::OCRepresentation r2 = mc2.representations()[0];
134         EXPECT_STREQ("res.1.1.0", r2.getDataModelVersions()[0].c_str());
135         EXPECT_STREQ("sh.1.1.0", r2.getDataModelVersions()[1].c_str());
136
137         OCPayloadDestroy(parsedDevice);
138     }
139
140     static const char uri1[] = "/testuri";
141     static char pfid1[] = "pfid";
142     static char mfgnm1[] = "mfgnm";
143     static char mfgurl1[] = "mfgurl";
144     static char modelnum1[] = "modelnum";
145     static char dom1[] = "dom";
146     static char pfver1[] = "pfver";
147     static char osver1[] = "osver";
148     static char hwver1[] = "hwver";
149     static char fwver1[] = "fwver";
150     static char url1[] = "url";
151     static char time1[] = "time";
152
153     // Platform Payloads
154     TEST(PlatformDiscoveryEncoding, Normal)
155     {
156         OCPlatformInfo info {pfid1, mfgnm1, mfgurl1, modelnum1, dom1, pfver1, osver1, hwver1,
157             fwver1, url1, time1};
158         OCPlatformPayload* platform = OCPlatformPayloadCreate(&info);
159         EXPECT_EQ(PAYLOAD_TYPE_PLATFORM, ((OCPayload*)platform)->type);
160         EXPECT_STREQ(pfid1, platform->info.platformID);
161         EXPECT_STREQ(mfgnm1, platform->info.manufacturerName);
162         EXPECT_STREQ(mfgurl1, platform->info.manufacturerUrl);
163         EXPECT_STREQ(modelnum1, platform->info.modelNumber);
164         EXPECT_STREQ(dom1, platform->info.dateOfManufacture);
165         EXPECT_STREQ(pfver1, platform->info.platformVersion);
166         EXPECT_STREQ(osver1, platform->info.operatingSystemVersion);
167         EXPECT_STREQ(hwver1, platform->info.hardwareVersion);
168         EXPECT_STREQ(fwver1, platform->info.firmwareVersion);
169         EXPECT_STREQ(url1, platform->info.supportUrl);
170         EXPECT_STREQ(time1, platform->info.systemTime);
171         EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, platform->interfaces->value);
172         EXPECT_STREQ(OC_RSRVD_INTERFACE_READ, platform->interfaces->next->value);
173         EXPECT_STREQ(OC_RSRVD_RESOURCE_TYPE_PLATFORM, platform->rt->value);
174
175         uint8_t* cborData;
176         size_t cborSize;
177         OCPayload* parsedPlatform;
178         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)platform, &cborData, &cborSize));
179         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedPlatform, PAYLOAD_TYPE_PLATFORM,
180                     cborData, cborSize));
181         OICFree(cborData);
182
183         EXPECT_EQ(platform->base.type, ((OCPlatformPayload*)parsedPlatform)->base.type);
184         OCPlatformPayload* platform2 = (OCPlatformPayload*)parsedPlatform;
185         EXPECT_STREQ(platform->info.platformID, platform2->info.platformID);
186         EXPECT_STREQ(platform->info.manufacturerName, platform->info.manufacturerName);
187         EXPECT_STREQ(platform->info.manufacturerUrl, platform->info.manufacturerUrl);
188         EXPECT_STREQ(platform->info.modelNumber, platform->info.modelNumber);
189         EXPECT_STREQ(platform->info.dateOfManufacture, platform->info.dateOfManufacture);
190         EXPECT_STREQ(platform->info.platformVersion, platform->info.platformVersion);
191         EXPECT_STREQ(platform->info.operatingSystemVersion, platform->info.operatingSystemVersion);
192         EXPECT_STREQ(platform->info.hardwareVersion, platform->info.hardwareVersion);
193         EXPECT_STREQ(platform->info.firmwareVersion, platform->info.firmwareVersion);
194         EXPECT_STREQ(platform->info.supportUrl, platform->info.supportUrl);
195         EXPECT_STREQ(platform->info.systemTime, platform2->info.systemTime);
196         EXPECT_STREQ(platform->interfaces->value, platform2->interfaces->value);
197         EXPECT_STREQ(platform->rt->value, platform2->rt->value);
198
199         OCPayloadDestroy((OCPayload*)platform);
200
201         OC::MessageContainer mc;
202         mc.setPayload(parsedPlatform);
203         EXPECT_EQ(1u, mc.representations().size());
204         const OC::OCRepresentation& r = mc.representations()[0];
205         EXPECT_STREQ(pfid1, r.getValue<std::string>(OC_RSRVD_PLATFORM_ID).c_str());
206         EXPECT_STREQ(mfgnm1, r.getValue<std::string>(OC_RSRVD_MFG_NAME).c_str());
207         EXPECT_STREQ(mfgurl1, r.getValue<std::string>(OC_RSRVD_MFG_URL).c_str());
208         EXPECT_STREQ(modelnum1, r.getValue<std::string>(OC_RSRVD_MODEL_NUM).c_str());
209         EXPECT_STREQ(dom1, r.getValue<std::string>(OC_RSRVD_MFG_DATE).c_str());
210         EXPECT_STREQ(pfver1, r.getValue<std::string>(OC_RSRVD_PLATFORM_VERSION).c_str());
211         EXPECT_STREQ(osver1, r.getValue<std::string>(OC_RSRVD_OS_VERSION).c_str());
212         EXPECT_STREQ(hwver1, r.getValue<std::string>(OC_RSRVD_HARDWARE_VERSION).c_str());
213         EXPECT_STREQ(fwver1, r.getValue<std::string>(OC_RSRVD_FIRMWARE_VERSION).c_str());
214         EXPECT_STREQ(url1, r.getValue<std::string>(OC_RSRVD_SUPPORT_URL).c_str());
215         EXPECT_STREQ(time1, r.getValue<std::string>(OC_RSRVD_SYSTEM_TIME).c_str());
216
217         OCPayloadDestroy(parsedPlatform);
218     }
219     TEST(PresencePayload, Normal)
220     {
221         uint32_t maxAge = 0;
222         uint32_t sequenceNumber = 0;
223         OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
224         OCPresencePayload *presence = OCPresencePayloadCreate(sequenceNumber, maxAge, trigger, uri1);
225
226         uint8_t* cborData;
227         size_t cborSize;
228         OCPayload* cparsed;
229         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)presence, &cborData, &cborSize));
230         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_PRESENCE,
231                     cborData, cborSize));
232         OCPayloadDestroy((OCPayload*)presence);
233         OICFree(cborData);
234
235         OCPresencePayload* parsed = ((OCPresencePayload*)cparsed);
236         EXPECT_EQ(sequenceNumber, parsed->sequenceNumber);
237         EXPECT_EQ(maxAge, parsed->maxAge);
238         EXPECT_EQ(trigger, parsed->trigger);
239         EXPECT_STREQ(uri1, parsed->resourceType);
240
241         OCPayloadDestroy(cparsed);
242     }
243     // Representation Payloads
244     TEST(RepresentationEncoding, BaseAttributeTypes)
245     {
246         OC::OCRepresentation startRep;
247         startRep.setNULL("NullAttr");
248         startRep.setValue("IntAttr", 77);
249         startRep.setValue("DoubleAttr", 3.333);
250         startRep.setValue("BoolAttr", true);
251         startRep.setValue("StringAttr", std::string("String attr"));
252         OC::MessageContainer mc1;
253         mc1.addRepresentation(startRep);
254
255         OCRepPayload* cstart = mc1.getPayload();
256         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
257
258         uint8_t* cborData;
259         size_t cborSize;
260         OCPayload* cparsed;
261         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
262         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
263                     cborData, cborSize));
264         OCPayloadDestroy((OCPayload*)cstart);
265         OICFree(cborData);
266
267         OC::MessageContainer mc2;
268         mc2.setPayload(cparsed);
269         EXPECT_EQ(1u, mc2.representations().size());
270         const OC::OCRepresentation& r = mc2.representations()[0];
271
272         EXPECT_TRUE(r.isNULL("NullAttr"));
273         EXPECT_EQ(77, r.getValue<int>("IntAttr"));
274         EXPECT_EQ(3.333, r.getValue<double>("DoubleAttr"));
275         EXPECT_EQ(true, r.getValue<bool>("BoolAttr"));
276         EXPECT_STREQ("String attr", r.getValue<std::string>("StringAttr").c_str());
277
278         OCPayloadDestroy(cparsed);
279     }
280
281     TEST(RepresentationEncoding, RepAttributeEmpty)
282     {
283         OC::OCRepresentation startRep;
284         std::vector<int> iarr {};
285         startRep["iarr"] = {};
286
287         OC::MessageContainer mc1;
288         mc1.addRepresentation(startRep);
289
290         OCRepPayload* cstart = mc1.getPayload();
291         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
292
293         uint8_t *cborData = NULL;
294         size_t cborSize = 0;
295         OCPayload *cparsed = NULL;
296         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
297         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
298                     cborData, cborSize));
299         OCPayloadDestroy((OCPayload*)cstart);
300         OICFree(cborData);
301
302         OC::MessageContainer mc2;
303         mc2.setPayload(cparsed);
304         EXPECT_EQ(1u, mc2.representations().size());
305         const OC::OCRepresentation& r = mc2.representations()[0];
306
307         std::vector<int> iarr2 = r["iarr"];
308
309         EXPECT_EQ(iarr, iarr2);
310         OCPayloadDestroy(cparsed);
311     }
312
313     TEST(RepresentationEncoding, RepAttribute)
314     {
315         OC::OCRepresentation startRep;
316         OC::OCRepresentation subRep;
317         subRep.setNULL("NullAttr");
318         subRep.setValue("IntAttr", 77);
319         subRep.setValue("DoubleAttr", 3.333);
320         subRep.setValue("BoolAttr", true);
321         subRep.setValue("StringAttr", std::string("String attr"));
322         std::vector<uint8_t> bin_data {5,3,4,5,6,0,34,2,4,5,6,3};
323         subRep.setValue("BinaryAttr", bin_data);
324         startRep.setValue("Sub", subRep);
325
326         OC::MessageContainer mc1;
327         mc1.addRepresentation(startRep);
328
329         OCRepPayload* cstart = mc1.getPayload();
330         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
331
332         uint8_t* cborData;
333         size_t cborSize;
334         OCPayload* cparsed;
335         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
336         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
337                     cborData, cborSize));
338         OCPayloadDestroy((OCPayload*)cstart);
339         OICFree(cborData);
340
341         OC::MessageContainer mc2;
342         mc2.setPayload(cparsed);
343         EXPECT_EQ(1u, mc2.representations().size());
344         const OC::OCRepresentation& r = mc2.representations()[0];
345
346         OC::OCRepresentation newSubRep = r["Sub"];
347
348         EXPECT_TRUE(newSubRep.isNULL("NullAttr"));
349         EXPECT_EQ(77, newSubRep.getValue<int>("IntAttr"));
350         EXPECT_EQ(3.333, newSubRep.getValue<double>("DoubleAttr"));
351         EXPECT_EQ(true, newSubRep.getValue<bool>("BoolAttr"));
352         EXPECT_STREQ("String attr", newSubRep.getValue<std::string>("StringAttr").c_str());
353         EXPECT_EQ(bin_data,
354                 newSubRep.getValue<std::vector<uint8_t>>("BinaryAttr"));
355         OCPayloadDestroy(cparsed);
356     }
357
358     TEST(RepresentationEncoding, OneDVectors)
359     {
360         // Setup
361         OC::OCRepresentation startRep;
362
363         OC::OCRepresentation subRep1;
364         OC::OCRepresentation subRep2;
365         OC::OCRepresentation subRep3;
366         subRep1.setNULL("NullAttr");
367         subRep1.setValue("IntAttr", 77);
368         subRep2.setValue("DoubleAttr", 3.333);
369         subRep2.setValue("BoolAttr", true);
370         subRep3.setValue("StringAttr", std::string("String attr"));
371
372         std::vector<int> iarr {1,2,3,4,5,6,7,8,9};
373         std::vector<double> darr {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
374         std::vector<bool> barr {false, true, false, false, true, true};
375         std::vector<std::string> strarr {"item1", "item2", "item3", "item4"};
376         std::vector<OC::OCRepresentation> objarr {subRep1, subRep2, subRep3};
377
378         startRep["iarr"] = iarr;
379         startRep["darr"] = darr;
380         startRep["barr"] = barr;
381         startRep["strarr"] = strarr;
382         startRep["objarr"] = objarr;
383
384         // Encode/decode
385         OC::MessageContainer mc1;
386         mc1.addRepresentation(startRep);
387
388         OCRepPayload* cstart = mc1.getPayload();
389         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
390
391         uint8_t* cborData;
392         size_t cborSize;
393         OCPayload* cparsed;
394         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
395         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
396                     cborData, cborSize));
397         OCPayloadDestroy((OCPayload*)cstart);
398         OICFree(cborData);
399
400         OC::MessageContainer mc2;
401         mc2.setPayload(cparsed);
402         EXPECT_EQ(1u, mc2.representations().size());
403         const OC::OCRepresentation& r = mc2.representations()[0];
404
405         // Test
406         std::vector<int> iarr2 = r["iarr"];
407         std::vector<double> darr2 = r["darr"];
408         std::vector<bool> barr2 = r["barr"];
409         std::vector<std::string> strarr2 = r["strarr"];
410         std::vector<OC::OCRepresentation> objarr2 = r["objarr"];
411
412         EXPECT_EQ(iarr, iarr2);
413         EXPECT_EQ(darr, darr2);
414         EXPECT_EQ(barr, barr2);
415         EXPECT_EQ(strarr, strarr2);
416         EXPECT_EQ(objarr, objarr2);
417         OCPayloadDestroy(cparsed);
418     }
419
420     TEST(RepresentationEncoding, TwoDVectors)
421     {
422         // Setup
423         OC::OCRepresentation startRep;
424
425         OC::OCRepresentation subRep1;
426         OC::OCRepresentation subRep2;
427         OC::OCRepresentation subRep3;
428         subRep1.setNULL("NullAttr");
429         subRep1.setValue("IntAttr", 77);
430         subRep2.setValue("DoubleAttr", 3.333);
431         subRep2.setValue("BoolAttr", true);
432         subRep3.setValue("StringAttr", std::string("String attr"));
433
434         std::vector<std::vector<int>> iarr {{1,2,3},{4,5,6},{7,8,9}};
435         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{7.7,8.8,9.9}};
436         std::vector<std::vector<bool>> barr {{false, true}, {false, false}, {true, true}};
437         std::vector<std::vector<std::string>> strarr {{"item1", "item2"}, {"item3", "item4"}};
438         std::vector<std::vector<OC::OCRepresentation>> objarr
439         {{subRep1, subRep2, subRep3}, {subRep3, subRep2, subRep1}};
440
441         startRep["iarr"] = iarr;
442         startRep["darr"] = darr;
443         startRep["barr"] = barr;
444         startRep["strarr"] = strarr;
445         startRep["objarr"] = objarr;
446
447         // Encode/decode
448         OC::MessageContainer mc1;
449         mc1.addRepresentation(startRep);
450
451         OCRepPayload* cstart = mc1.getPayload();
452         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
453
454         uint8_t* cborData;
455         size_t cborSize;
456         OCPayload* cparsed;
457         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
458         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
459                     cborData, cborSize));
460         OCPayloadDestroy((OCPayload*)cstart);
461         OICFree(cborData);
462
463         OC::MessageContainer mc2;
464         mc2.setPayload(cparsed);
465         EXPECT_EQ(1u, mc2.representations().size());
466         const OC::OCRepresentation& r = mc2.representations()[0];
467
468         // Test
469         std::vector<std::vector<int>> iarr2 = r["iarr"];
470         std::vector<std::vector<double>> darr2 = r["darr"];
471         std::vector<std::vector<bool>> barr2 = r["barr"];
472         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
473         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
474
475         EXPECT_EQ(iarr, iarr2);
476         EXPECT_EQ(darr, darr2);
477         EXPECT_EQ(barr, barr2);
478         EXPECT_EQ(strarr, strarr2);
479         EXPECT_EQ(objarr, objarr2);
480         OCPayloadDestroy(cparsed);
481     }
482
483     TEST(RepresentationEncoding, TwoDVectorsJagged)
484     {
485         // Setup
486         OC::OCRepresentation startRep;
487
488         OC::OCRepresentation subRep1;
489         OC::OCRepresentation subRep2;
490         OC::OCRepresentation subRep3;
491         subRep1.setNULL("NullAttr");
492         subRep1.setValue("IntAttr", 77);
493         subRep2.setValue("DoubleAttr", 3.333);
494         subRep2.setValue("BoolAttr", true);
495         subRep3.setValue("StringAttr", std::string("String attr"));
496
497         std::vector<std::vector<int>> iarr {{1,2,3},{4,6},{7,8,9}};
498         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{8.8,9.9}};
499         std::vector<std::vector<bool>> barr {{false, true}, {false}, {true, true}};
500         std::vector<std::vector<std::string>> strarr {{"item1"}, {"item3", "item4"}};
501         std::vector<std::vector<OC::OCRepresentation>> objarr
502         {{subRep1, subRep3}, {subRep3, subRep2, subRep1}};
503
504         startRep["iarr"] = iarr;
505         startRep["darr"] = darr;
506         startRep["barr"] = barr;
507         startRep["strarr"] = strarr;
508         startRep["objarr"] = objarr;
509
510         // Encode/decode
511         OC::MessageContainer mc1;
512         mc1.addRepresentation(startRep);
513
514         OCRepPayload* cstart = mc1.getPayload();
515         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
516
517         uint8_t* cborData;
518         size_t cborSize;
519         OCPayload* cparsed;
520         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
521         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
522                     cborData, cborSize));
523         OCPayloadDestroy((OCPayload*)cstart);
524         OICFree(cborData);
525
526         OC::MessageContainer mc2;
527         mc2.setPayload(cparsed);
528         EXPECT_EQ(1u, mc2.representations().size());
529         const OC::OCRepresentation& r = mc2.representations()[0];
530
531         // Test
532         std::vector<std::vector<int>> iarr2 = r["iarr"];
533         std::vector<std::vector<double>> darr2 = r["darr"];
534         std::vector<std::vector<bool>> barr2 = r["barr"];
535         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
536         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
537
538         // Note: due to the way that the CSDK works, all 2d arrays need to be rectangular.
539         // Since std::vector doesn't require this, items received on the other side end up
540         // being backfilled.  This section removes the backfilling
541         iarr2[1].pop_back();
542         darr2[2].pop_back();
543         barr2[1].pop_back();
544         strarr2[0].pop_back();
545         objarr2[0].pop_back();
546
547         EXPECT_EQ(iarr, iarr2);
548         EXPECT_EQ(darr, darr2);
549         EXPECT_EQ(barr, barr2);
550         EXPECT_EQ(strarr, strarr2);
551         EXPECT_EQ(objarr, objarr2);
552         OCPayloadDestroy(cparsed);
553     }
554
555     TEST(RepresentationEncoding, ThreeDVectors)
556     {
557         // Setup
558         OC::OCRepresentation startRep;
559
560         OC::OCRepresentation subRep1;
561         OC::OCRepresentation subRep2;
562         OC::OCRepresentation subRep3;
563         subRep1.setNULL("NullAttr");
564         subRep1.setValue("IntAttr", 77);
565         subRep2.setValue("DoubleAttr", 3.333);
566         subRep2.setValue("BoolAttr", true);
567         subRep3.setValue("StringAttr", std::string("String attr"));
568
569         std::vector<std::vector<std::vector<int>>> iarr
570             {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}},{{13,14,15},{16,17,18}}};
571         std::vector<std::vector<std::vector<double>>> darr
572             {{{1.1,2.2,3.3},{4.4,5.5,6.6}},
573                 {{7.7,8.7,9.7},{10.7,11.7,12.7}},
574                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}};
575         std::vector<std::vector<std::vector<bool>>> barr
576             {{{false, true},{true, false}},{{false, true},{true, false}}};
577         std::vector<std::vector<std::vector<std::string>>> strarr
578             {
579                 {{"item1", "item2"},{"item3", "item4"}},
580                 {{"item5", "item6"},{"item7", "item8"}},
581                 {{"item9", "item10"},{"item11", ""}}
582             };
583         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
584             {
585                 {{subRep1, subRep2},{subRep3, subRep1}},
586                 {{subRep2, subRep3},{subRep2, subRep1}},
587                 {{subRep3, subRep2},{subRep1, subRep2}}
588             };
589
590         startRep["iarr"] = iarr;
591         startRep["darr"] = darr;
592         startRep["barr"] = barr;
593         startRep["strarr"] = strarr;
594         startRep["objarr"] = objarr;
595
596         // Encode/decode
597         OC::MessageContainer mc1;
598         mc1.addRepresentation(startRep);
599
600         OCRepPayload* cstart = mc1.getPayload();
601         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
602
603         uint8_t* cborData;
604         size_t cborSize;
605         OCPayload* cparsed;
606         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
607         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
608                     cborData, cborSize));
609         OCPayloadDestroy((OCPayload*)cstart);
610         OICFree(cborData);
611
612         OC::MessageContainer mc2;
613         mc2.setPayload(cparsed);
614         EXPECT_EQ(1u, mc2.representations().size());
615         const OC::OCRepresentation& r = mc2.representations()[0];
616
617         // Test
618         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
619         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
620         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
621         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
622         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
623
624         EXPECT_EQ(iarr, iarr2);
625         EXPECT_EQ(darr, darr2);
626         EXPECT_EQ(barr, barr2);
627         EXPECT_EQ(strarr, strarr2);
628         EXPECT_EQ(objarr, objarr2);
629         OCPayloadDestroy(cparsed);
630     }
631
632     TEST(RepresentationEncoding, ThreeDVectorsJagged)
633     {
634         // Setup
635         OC::OCRepresentation startRep;
636
637         OC::OCRepresentation subRep1;
638         OC::OCRepresentation subRep2;
639         OC::OCRepresentation subRep3;
640         subRep1.setNULL("NullAttr");
641         subRep1.setValue("IntAttr", 77);
642         subRep2.setValue("DoubleAttr", 3.333);
643         subRep2.setValue("BoolAttr", true);
644         subRep3.setValue("StringAttr", std::string("String attr"));
645
646         std::vector<std::vector<std::vector<int>>> iarr
647             {
648                 {{1,2,3},{4,5,6}},
649                 {{7,8,9},{10,12}},
650                 {{13,14,15},{16,17,18}}
651             };
652         std::vector<std::vector<std::vector<double>>> darr
653             {
654                 {{1.1,2.2,3.3},{4.4,5.5,6.6}},
655                 {{7.7,8.7,9.7},{10.7,12.7}},
656                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}
657             };
658         std::vector<std::vector<std::vector<bool>>> barr
659             {
660                 {{false, true},{true}},
661                 {{false, true},{true, false}}
662             };
663         std::vector<std::vector<std::vector<std::string>>> strarr
664             {
665                 {{"item1", "item2"},{"item3", "item4"}},
666                 {{"item5", "item6"},{"item8"}},
667                 {{"item9", "item10"},{"item11", ""}}
668             };
669         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
670             {
671                 {{subRep1, subRep2},{subRep3, subRep1}},
672                 {{subRep2, subRep3},{subRep2}},
673                 {{subRep3, subRep2}}
674             };
675
676         startRep["iarr"] = iarr;
677         startRep["darr"] = darr;
678         startRep["barr"] = barr;
679         startRep["strarr"] = strarr;
680         startRep["objarr"] = objarr;
681
682         // Encode/decode
683         OC::MessageContainer mc1;
684         mc1.addRepresentation(startRep);
685
686         OCRepPayload* cstart = mc1.getPayload();
687         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
688
689         uint8_t* cborData;
690         size_t cborSize;
691         OCPayload* cparsed;
692         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
693         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
694                     cborData, cborSize));
695         OCPayloadDestroy((OCPayload*)cstart);
696         OICFree(cborData);
697
698         OC::MessageContainer mc2;
699         mc2.setPayload(cparsed);
700         EXPECT_EQ(1u, mc2.representations().size());
701         const OC::OCRepresentation& r = mc2.representations()[0];
702
703         // Test
704         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
705         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
706         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
707         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
708         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
709
710         // Note: due to the way that the CSDK works, all 3d arrays need to be cuboidal.
711         // Since std::vector doesn't require this, items received on the other side end up
712         // being backfilled.  This section removes the backfilling
713         iarr2[1][1].pop_back();
714         darr2[1][1].pop_back();
715         barr2[0][1].pop_back();
716         strarr2[1][1].pop_back();
717         objarr2[1][1].pop_back();
718         objarr2[2].pop_back();
719
720         EXPECT_EQ(iarr, iarr2);
721         EXPECT_EQ(darr, darr2);
722         EXPECT_EQ(barr, barr2);
723         EXPECT_EQ(strarr, strarr2);
724         EXPECT_EQ(objarr, objarr2);
725         OCPayloadDestroy(cparsed);
726     }
727
728     TEST(DiscoveryRTandIF, SingleItemNormal)
729     {
730         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
731         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
732         payload->sid = OICStrdup(sid1);
733         payload->resources = resource;
734
735         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem"));
736         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem"));
737
738         resource->uri = OICStrdup("/uri/thing");
739
740         uint8_t* cborData;
741         size_t cborSize;
742         OCPayload* cparsed;
743
744         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
745         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
746                     cborData, cborSize));
747
748         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
749         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
750
751         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
752         EXPECT_EQ(NULL, parsedResource->next);
753         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
754         EXPECT_EQ(NULL, parsedResource->types->next);
755         EXPECT_EQ(NULL, parsedResource->interfaces->next);
756         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
757
758         OICFree(cborData);
759         OCPayloadDestroy(cparsed);
760         OCDiscoveryPayloadDestroy(payload);
761     }
762
763     TEST(DiscoveryRTandIF, SingleItemFrontTrim)
764     {
765         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
766         payload->sid = OICStrdup(sid1);
767         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
768         payload->resources = resource;
769
770         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem"));
771         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem"));
772         resource->uri = OICStrdup("/uri/thing");
773
774         uint8_t* cborData;
775         size_t cborSize;
776         OCPayload* cparsed;
777
778         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
779         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
780                     cborData, cborSize));
781
782         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
783         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
784
785         EXPECT_EQ(NULL, parsedResource->next);
786         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
787         EXPECT_EQ(NULL, parsedResource->types->next);
788         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
789         EXPECT_EQ(NULL, parsedResource->interfaces->next);
790         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
791
792         OICFree(cborData);
793         OCPayloadDestroy(cparsed);
794         OCDiscoveryPayloadDestroy(payload);
795     }
796
797     TEST(DiscoveryRTandIF, SingleItemBackTrim)
798     {
799         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
800         payload->sid = OICStrdup(sid1);
801         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
802         payload->resources = resource;
803
804         OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem    ");
805         OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem    ");
806         resource->uri = OICStrdup("/uri/thing");
807
808         uint8_t* cborData;
809         size_t cborSize;
810         OCPayload* cparsed;
811
812         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
813         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
814                     cborData, cborSize));
815
816         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
817         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
818
819         EXPECT_EQ(NULL, parsedResource->next);
820         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
821         EXPECT_EQ(NULL, parsedResource->types->next);
822         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
823         EXPECT_EQ(NULL, parsedResource->interfaces->next);
824         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
825
826         OICFree(cborData);
827         OCPayloadDestroy(cparsed);
828         OCDiscoveryPayloadDestroy(payload);
829     }
830     TEST(DiscoveryRTandIF, SingleItemBothTrim)
831     {
832         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
833         payload->sid = OICStrdup(sid1);
834         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
835         payload->resources = resource;
836
837         OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem    ");
838         OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem     ");
839         resource->uri = OICStrdup("/uri/thing");
840
841         uint8_t* cborData;
842         size_t cborSize;
843         OCPayload* cparsed;
844
845         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
846         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
847                     cborData, cborSize));
848
849         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
850         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
851
852         EXPECT_EQ(NULL, parsedResource->next);
853         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
854         EXPECT_EQ(NULL, parsedResource->types->next);
855         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
856         EXPECT_EQ(NULL, parsedResource->interfaces->next);
857         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
858
859         OICFree(cborData);
860         OCPayloadDestroy(cparsed);
861         OCDiscoveryPayloadDestroy(payload);
862     }
863     TEST(DiscoveryRTandIF, MultiItemsNormal)
864     {
865         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
866         payload->sid = OICStrdup(sid1);
867         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
868         payload->resources = resource;
869
870         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem");
871         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem");
872         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem");
873         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem");
874         resource->uri = OICStrdup("/uri/thing");
875
876         uint8_t* cborData;
877         size_t cborSize;
878         OCPayload* cparsed;
879
880         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
881         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
882                     cborData, cborSize));
883
884         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
885         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
886
887         EXPECT_EQ(NULL, parsedResource->next);
888         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
889         EXPECT_EQ(NULL, parsedResource->types->next->next);
890         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
891         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
892         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
893         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
894         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
895
896         OICFree(cborData);
897         OCPayloadDestroy(cparsed);
898         OCDiscoveryPayloadDestroy(payload);
899     }
900     TEST(DiscoveryRTandIF, MultiItemExtraLeadSpaces)
901     {
902         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
903         payload->sid = OICStrdup(sid1);
904         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
905         payload->resources = resource;
906
907         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem");
908         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem");
909         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem");
910         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem");
911         resource->uri = OICStrdup("/uri/thing");
912
913         uint8_t* cborData;
914         size_t cborSize;
915         OCPayload* cparsed;
916
917         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
918         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
919                     cborData, cborSize));
920
921         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
922         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
923
924         EXPECT_EQ(NULL, parsedResource->next);
925         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
926         EXPECT_EQ(NULL, parsedResource->types->next->next);
927         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
928         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
929         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
930         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
931         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
932
933         OICFree(cborData);
934         OCPayloadDestroy(cparsed);
935         OCDiscoveryPayloadDestroy(payload);
936     }
937     TEST(DiscoveryRTandIF, MultiItemExtraTrailSpaces)
938     {
939         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
940         payload->sid = OICStrdup(sid1);
941         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
942         payload->resources = resource;
943
944         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem  ");
945         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem  ");
946         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem  ");
947         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem  ");
948         resource->uri = OICStrdup("/uri/thing");
949
950         uint8_t* cborData;
951         size_t cborSize;
952         OCPayload* cparsed;
953
954         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
955         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
956                     cborData, cborSize));
957
958         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
959         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
960
961         EXPECT_EQ(NULL, parsedResource->next);
962         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
963         EXPECT_EQ(NULL, parsedResource->types->next->next);
964         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
965         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
966         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
967         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
968         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
969
970         OICFree(cborData);
971         OCPayloadDestroy(cparsed);
972         OCDiscoveryPayloadDestroy(payload);
973     }
974     TEST(DiscoveryRTandIF, MultiItemBothSpaces)
975     {
976         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
977         payload->sid = OICStrdup(sid1);
978         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
979         payload->resources = resource;
980
981         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem  ");
982         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem  ");
983         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem  ");
984         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem  ");
985         resource->uri = OICStrdup("/uri/thing");
986
987         uint8_t* cborData;
988         size_t cborSize;
989         OCPayload* cparsed;
990
991         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
992         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
993                     cborData, cborSize));
994
995         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
996         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
997
998         EXPECT_EQ(NULL, parsedResource->next);
999         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1000         EXPECT_EQ(NULL, parsedResource->types->next->next);
1001         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1002         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1003         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1004         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1005         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1006
1007         OICFree(cborData);
1008         OCPayloadDestroy(cparsed);
1009         OCDiscoveryPayloadDestroy(payload);
1010     }
1011     TEST(RepresentationEncodingRTandIF, SingleItemNormal)
1012     {
1013         OCRepPayload* payload = OCRepPayloadCreate();
1014         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1015         OCRepPayloadAddInterface(payload, "if.firstitem");
1016
1017         uint8_t* cborData;
1018         size_t cborSize;
1019         OCPayload* cparsed;
1020
1021         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1022         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1023                     cborData, cborSize));
1024
1025         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1026
1027         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1028         EXPECT_EQ(NULL, parsedPayload->types->next);
1029         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1030         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1031
1032         OICFree(cborData);
1033         OCRepPayloadDestroy(payload);
1034         OCPayloadDestroy(cparsed);
1035     }
1036     TEST(RepresentationEncodingRTandIF, SingleItemFrontTrim)
1037     {
1038         OCRepPayload* payload = OCRepPayloadCreate();
1039         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1040         OCRepPayloadAddInterface(payload, "  if.firstitem");
1041
1042         uint8_t* cborData;
1043         size_t cborSize;
1044         OCPayload* cparsed;
1045
1046         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1047         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1048                     cborData, cborSize));
1049
1050         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1051
1052         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1053         EXPECT_EQ(NULL, parsedPayload->types->next);
1054         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1055         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1056
1057
1058         OICFree(cborData);
1059         OCRepPayloadDestroy(payload);
1060         OCPayloadDestroy(cparsed);
1061     }
1062     TEST(RepresentationEncodingRTandIF, SingleItemBackTrim)
1063     {
1064         OCRepPayload* payload = OCRepPayloadCreate();
1065         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1066         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1067
1068         uint8_t* cborData;
1069         size_t cborSize;
1070         OCPayload* cparsed;
1071
1072         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1073         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1074                     cborData, cborSize));
1075
1076         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1077
1078         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1079         EXPECT_EQ(NULL, parsedPayload->types->next);
1080         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1081         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1082
1083
1084         OICFree(cborData);
1085         OCRepPayloadDestroy(payload);
1086         OCPayloadDestroy(cparsed);
1087     }
1088     TEST(RepresentationEncodingRTandIF, SingleItemBothTrim)
1089     {
1090         OCRepPayload* payload = OCRepPayloadCreate();
1091         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1092         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1093
1094         uint8_t* cborData;
1095         size_t cborSize;
1096         OCPayload* cparsed;
1097
1098         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1099         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1100                     cborData, cborSize));
1101
1102         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1103
1104         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1105         EXPECT_EQ(NULL, parsedPayload->types->next);
1106         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1107         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1108
1109
1110         OICFree(cborData);
1111         OCRepPayloadDestroy(payload);
1112         OCPayloadDestroy(cparsed);
1113     }
1114     TEST(RepresentationEncodingRTandIF, MultiItemsNormal)
1115     {
1116         OCRepPayload* payload = OCRepPayloadCreate();
1117         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1118         OCRepPayloadAddResourceType(payload, "rt.seconditem");
1119         OCRepPayloadAddInterface(payload, "if.firstitem");
1120         OCRepPayloadAddInterface(payload, "if.seconditem");
1121
1122         uint8_t* cborData;
1123         size_t cborSize;
1124         OCPayload* cparsed;
1125
1126         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1127         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1128                     cborData, cborSize));
1129
1130         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1131
1132         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1133         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1134         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1135         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1136         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1137         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1138
1139
1140         OICFree(cborData);
1141         OCRepPayloadDestroy(payload);
1142         OCPayloadDestroy(cparsed);
1143     }
1144     TEST(RepresentationEncodingRTandIF, MultiItemExtraLeadSpaces)
1145     {
1146         OCRepPayload* payload = OCRepPayloadCreate();
1147         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1148         OCRepPayloadAddResourceType(payload, "  rt.seconditem");
1149         OCRepPayloadAddInterface(payload, "  if.firstitem");
1150         OCRepPayloadAddInterface(payload, "  if.seconditem");
1151
1152         uint8_t* cborData;
1153         size_t cborSize;
1154         OCPayload* cparsed;
1155
1156         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1157         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1158                     cborData, cborSize));
1159
1160         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1161
1162         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1163         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1164         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1165         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1166         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1167         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1168
1169
1170         OICFree(cborData);
1171         OCRepPayloadDestroy(payload);
1172         OCPayloadDestroy(cparsed);
1173     }
1174     TEST(RepresentationEncodingRTandIF, MultiItemExtraTrailSpaces)
1175     {
1176         OCRepPayload* payload = OCRepPayloadCreate();
1177         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1178         OCRepPayloadAddResourceType(payload, "rt.seconditem  ");
1179         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1180         OCRepPayloadAddInterface(payload, "if.seconditem  ");
1181
1182         uint8_t* cborData;
1183         size_t cborSize;
1184         OCPayload* cparsed;
1185
1186         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1187         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1188                     cborData, cborSize));
1189
1190         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1191
1192         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1193         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1194         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1195         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1196         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1197         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1198
1199
1200         OICFree(cborData);
1201         OCRepPayloadDestroy(payload);
1202         OCPayloadDestroy(cparsed);
1203     }
1204     TEST(RepresentationEncodingRTandIF, MultiItemExtraMiddleSpaces)
1205     {
1206         OCRepPayload* payload = OCRepPayloadCreate();
1207         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1208         OCRepPayloadAddResourceType(payload, "  rt.seconditem  ");
1209         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1210         OCRepPayloadAddInterface(payload, "  if.seconditem  ");
1211
1212         uint8_t* cborData;
1213         size_t cborSize;
1214         OCPayload* cparsed;
1215
1216         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1217         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1218                     cborData, cborSize));
1219
1220         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1221
1222         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1223         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1224         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1225         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1226         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1227         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1228
1229
1230         OICFree(cborData);
1231         OCRepPayloadDestroy(payload);
1232         OCPayloadDestroy(cparsed);
1233     }
1234     TEST(RepresentationEncodingRTandIF, TestPayloadContents)
1235     {
1236         OC::OCRepresentation subRep1;
1237         std::vector<std::string> types;
1238         types.push_back("rt.firstitem");
1239         std::vector<std::string> interfaces;
1240         interfaces.push_back("if.firstitem");
1241         subRep1.setResourceTypes(types);
1242         subRep1.setResourceInterfaces(interfaces);
1243         subRep1.setNULL("NullAttr");
1244         subRep1.setValue("IntAttr", 77);
1245         subRep1.setValue("DoubleAttr", 3.333);
1246         subRep1.setValue("BoolAttr", true);
1247         subRep1.setValue("StringAttr", std::string("String attr"));
1248
1249         OC::MessageContainer mc1;
1250         mc1.addRepresentation(subRep1);
1251
1252         OCRepPayload *repPayload = mc1.getPayload();
1253         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, repPayload->base.type);
1254
1255         uint8_t *cborData = NULL;
1256         size_t cborSize = 0;
1257         OCPayload *cparsed = NULL;
1258
1259         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)repPayload, &cborData, &cborSize));
1260         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1261                     cborData, cborSize));
1262
1263         OCRepPayload *parsedPayload = (OCRepPayload *)cparsed;
1264         EXPECT_EQ(NULL, parsedPayload->uri);
1265         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1266         EXPECT_EQ(NULL, parsedPayload->types->next);
1267         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1268         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1269
1270         // To make sure rt and if are not duplicated.
1271         EXPECT_STREQ("BoolAttr", parsedPayload->values->name);
1272         EXPECT_EQ(true, parsedPayload->values->b);
1273         EXPECT_EQ(OCREP_PROP_BOOL, parsedPayload->values->type);
1274         parsedPayload->values = parsedPayload->values->next;
1275
1276         EXPECT_STREQ("DoubleAttr", parsedPayload->values->name);
1277         EXPECT_EQ(OCREP_PROP_DOUBLE, parsedPayload->values->type);
1278         EXPECT_EQ(3.3330000000000002, parsedPayload->values->d);
1279         parsedPayload->values = parsedPayload->values->next;
1280
1281         EXPECT_STREQ("IntAttr", parsedPayload->values->name);
1282         EXPECT_EQ(77, parsedPayload->values->i);
1283         EXPECT_EQ(OCREP_PROP_INT, parsedPayload->values->type);
1284         parsedPayload->values = parsedPayload->values->next;
1285
1286         EXPECT_STREQ("NullAttr", parsedPayload->values->name);
1287         EXPECT_EQ(OCREP_PROP_NULL, parsedPayload->values->type);
1288         parsedPayload->values = parsedPayload->values->next;
1289
1290         EXPECT_STREQ("StringAttr", parsedPayload->values->name);
1291         EXPECT_STREQ("String attr", parsedPayload->values->str);
1292         EXPECT_EQ(OCREP_PROP_STRING, parsedPayload->values->type);
1293         parsedPayload->values = parsedPayload->values->next;
1294
1295         EXPECT_EQ(NULL, parsedPayload->values);
1296
1297         OICFree(cborData);
1298         OCRepPayloadDestroy(repPayload);
1299         OCPayloadDestroy(cparsed);
1300     }
1301 }