Imported Upstream version 1.1.1
[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         startRep.setValue("Sub", subRep);
323
324         OC::MessageContainer mc1;
325         mc1.addRepresentation(startRep);
326
327         OCRepPayload* cstart = mc1.getPayload();
328         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
329
330         uint8_t* cborData;
331         size_t cborSize;
332         OCPayload* cparsed;
333         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
334         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
335                     cborData, cborSize));
336         OCPayloadDestroy((OCPayload*)cstart);
337         OICFree(cborData);
338
339         OC::MessageContainer mc2;
340         mc2.setPayload(cparsed);
341         EXPECT_EQ(1u, mc2.representations().size());
342         const OC::OCRepresentation& r = mc2.representations()[0];
343
344         OC::OCRepresentation newSubRep = r["Sub"];
345
346         EXPECT_TRUE(newSubRep.isNULL("NullAttr"));
347         EXPECT_EQ(77, newSubRep.getValue<int>("IntAttr"));
348         EXPECT_EQ(3.333, newSubRep.getValue<double>("DoubleAttr"));
349         EXPECT_EQ(true, newSubRep.getValue<bool>("BoolAttr"));
350         EXPECT_STREQ("String attr", newSubRep.getValue<std::string>("StringAttr").c_str());
351         OCPayloadDestroy(cparsed);
352     }
353
354     TEST(RepresentationEncoding, OneDVectors)
355     {
356         // Setup
357         OC::OCRepresentation startRep;
358
359         OC::OCRepresentation subRep1;
360         OC::OCRepresentation subRep2;
361         OC::OCRepresentation subRep3;
362         subRep1.setNULL("NullAttr");
363         subRep1.setValue("IntAttr", 77);
364         subRep2.setValue("DoubleAttr", 3.333);
365         subRep2.setValue("BoolAttr", true);
366         subRep3.setValue("StringAttr", std::string("String attr"));
367
368         std::vector<int> iarr {1,2,3,4,5,6,7,8,9};
369         std::vector<double> darr {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
370         std::vector<bool> barr {false, true, false, false, true, true};
371         std::vector<std::string> strarr {"item1", "item2", "item3", "item4"};
372         std::vector<OC::OCRepresentation> objarr {subRep1, subRep2, subRep3};
373
374         startRep["iarr"] = iarr;
375         startRep["darr"] = darr;
376         startRep["barr"] = barr;
377         startRep["strarr"] = strarr;
378         startRep["objarr"] = objarr;
379
380         // Encode/decode
381         OC::MessageContainer mc1;
382         mc1.addRepresentation(startRep);
383
384         OCRepPayload* cstart = mc1.getPayload();
385         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
386
387         uint8_t* cborData;
388         size_t cborSize;
389         OCPayload* cparsed;
390         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
391         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
392                     cborData, cborSize));
393         OCPayloadDestroy((OCPayload*)cstart);
394         OICFree(cborData);
395
396         OC::MessageContainer mc2;
397         mc2.setPayload(cparsed);
398         EXPECT_EQ(1u, mc2.representations().size());
399         const OC::OCRepresentation& r = mc2.representations()[0];
400
401         // Test
402         std::vector<int> iarr2 = r["iarr"];
403         std::vector<double> darr2 = r["darr"];
404         std::vector<bool> barr2 = r["barr"];
405         std::vector<std::string> strarr2 = r["strarr"];
406         std::vector<OC::OCRepresentation> objarr2 = r["objarr"];
407
408         EXPECT_EQ(iarr, iarr2);
409         EXPECT_EQ(darr, darr2);
410         EXPECT_EQ(barr, barr2);
411         EXPECT_EQ(strarr, strarr2);
412         EXPECT_EQ(objarr, objarr2);
413         OCPayloadDestroy(cparsed);
414     }
415
416     TEST(RepresentationEncoding, TwoDVectors)
417     {
418         // Setup
419         OC::OCRepresentation startRep;
420
421         OC::OCRepresentation subRep1;
422         OC::OCRepresentation subRep2;
423         OC::OCRepresentation subRep3;
424         subRep1.setNULL("NullAttr");
425         subRep1.setValue("IntAttr", 77);
426         subRep2.setValue("DoubleAttr", 3.333);
427         subRep2.setValue("BoolAttr", true);
428         subRep3.setValue("StringAttr", std::string("String attr"));
429
430         std::vector<std::vector<int>> iarr {{1,2,3},{4,5,6},{7,8,9}};
431         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{7.7,8.8,9.9}};
432         std::vector<std::vector<bool>> barr {{false, true}, {false, false}, {true, true}};
433         std::vector<std::vector<std::string>> strarr {{"item1", "item2"}, {"item3", "item4"}};
434         std::vector<std::vector<OC::OCRepresentation>> objarr
435         {{subRep1, subRep2, subRep3}, {subRep3, subRep2, subRep1}};
436
437         startRep["iarr"] = iarr;
438         startRep["darr"] = darr;
439         startRep["barr"] = barr;
440         startRep["strarr"] = strarr;
441         startRep["objarr"] = objarr;
442
443         // Encode/decode
444         OC::MessageContainer mc1;
445         mc1.addRepresentation(startRep);
446
447         OCRepPayload* cstart = mc1.getPayload();
448         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
449
450         uint8_t* cborData;
451         size_t cborSize;
452         OCPayload* cparsed;
453         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
454         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
455                     cborData, cborSize));
456         OCPayloadDestroy((OCPayload*)cstart);
457         OICFree(cborData);
458
459         OC::MessageContainer mc2;
460         mc2.setPayload(cparsed);
461         EXPECT_EQ(1u, mc2.representations().size());
462         const OC::OCRepresentation& r = mc2.representations()[0];
463
464         // Test
465         std::vector<std::vector<int>> iarr2 = r["iarr"];
466         std::vector<std::vector<double>> darr2 = r["darr"];
467         std::vector<std::vector<bool>> barr2 = r["barr"];
468         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
469         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
470
471         EXPECT_EQ(iarr, iarr2);
472         EXPECT_EQ(darr, darr2);
473         EXPECT_EQ(barr, barr2);
474         EXPECT_EQ(strarr, strarr2);
475         EXPECT_EQ(objarr, objarr2);
476         OCPayloadDestroy(cparsed);
477     }
478
479     TEST(RepresentationEncoding, TwoDVectorsJagged)
480     {
481         // Setup
482         OC::OCRepresentation startRep;
483
484         OC::OCRepresentation subRep1;
485         OC::OCRepresentation subRep2;
486         OC::OCRepresentation subRep3;
487         subRep1.setNULL("NullAttr");
488         subRep1.setValue("IntAttr", 77);
489         subRep2.setValue("DoubleAttr", 3.333);
490         subRep2.setValue("BoolAttr", true);
491         subRep3.setValue("StringAttr", std::string("String attr"));
492
493         std::vector<std::vector<int>> iarr {{1,2,3},{4,6},{7,8,9}};
494         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{8.8,9.9}};
495         std::vector<std::vector<bool>> barr {{false, true}, {false}, {true, true}};
496         std::vector<std::vector<std::string>> strarr {{"item1"}, {"item3", "item4"}};
497         std::vector<std::vector<OC::OCRepresentation>> objarr
498         {{subRep1, subRep3}, {subRep3, subRep2, subRep1}};
499
500         startRep["iarr"] = iarr;
501         startRep["darr"] = darr;
502         startRep["barr"] = barr;
503         startRep["strarr"] = strarr;
504         startRep["objarr"] = objarr;
505
506         // Encode/decode
507         OC::MessageContainer mc1;
508         mc1.addRepresentation(startRep);
509
510         OCRepPayload* cstart = mc1.getPayload();
511         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
512
513         uint8_t* cborData;
514         size_t cborSize;
515         OCPayload* cparsed;
516         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
517         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
518                     cborData, cborSize));
519         OCPayloadDestroy((OCPayload*)cstart);
520         OICFree(cborData);
521
522         OC::MessageContainer mc2;
523         mc2.setPayload(cparsed);
524         EXPECT_EQ(1u, mc2.representations().size());
525         const OC::OCRepresentation& r = mc2.representations()[0];
526
527         // Test
528         std::vector<std::vector<int>> iarr2 = r["iarr"];
529         std::vector<std::vector<double>> darr2 = r["darr"];
530         std::vector<std::vector<bool>> barr2 = r["barr"];
531         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
532         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
533
534         // Note: due to the way that the CSDK works, all 2d arrays need to be rectangular.
535         // Since std::vector doesn't require this, items received on the other side end up
536         // being backfilled.  This section removes the backfilling
537         iarr2[1].pop_back();
538         darr2[2].pop_back();
539         barr2[1].pop_back();
540         strarr2[0].pop_back();
541         objarr2[0].pop_back();
542
543         EXPECT_EQ(iarr, iarr2);
544         EXPECT_EQ(darr, darr2);
545         EXPECT_EQ(barr, barr2);
546         EXPECT_EQ(strarr, strarr2);
547         EXPECT_EQ(objarr, objarr2);
548         OCPayloadDestroy(cparsed);
549     }
550
551     TEST(RepresentationEncoding, ThreeDVectors)
552     {
553         // Setup
554         OC::OCRepresentation startRep;
555
556         OC::OCRepresentation subRep1;
557         OC::OCRepresentation subRep2;
558         OC::OCRepresentation subRep3;
559         subRep1.setNULL("NullAttr");
560         subRep1.setValue("IntAttr", 77);
561         subRep2.setValue("DoubleAttr", 3.333);
562         subRep2.setValue("BoolAttr", true);
563         subRep3.setValue("StringAttr", std::string("String attr"));
564
565         std::vector<std::vector<std::vector<int>>> iarr
566             {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}},{{13,14,15},{16,17,18}}};
567         std::vector<std::vector<std::vector<double>>> darr
568             {{{1.1,2.2,3.3},{4.4,5.5,6.6}},
569                 {{7.7,8.7,9.7},{10.7,11.7,12.7}},
570                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}};
571         std::vector<std::vector<std::vector<bool>>> barr
572             {{{false, true},{true, false}},{{false, true},{true, false}}};
573         std::vector<std::vector<std::vector<std::string>>> strarr
574             {
575                 {{"item1", "item2"},{"item3", "item4"}},
576                 {{"item5", "item6"},{"item7", "item8"}},
577                 {{"item9", "item10"},{"item11", ""}}
578             };
579         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
580             {
581                 {{subRep1, subRep2},{subRep3, subRep1}},
582                 {{subRep2, subRep3},{subRep2, subRep1}},
583                 {{subRep3, subRep2},{subRep1, subRep2}}
584             };
585
586         startRep["iarr"] = iarr;
587         startRep["darr"] = darr;
588         startRep["barr"] = barr;
589         startRep["strarr"] = strarr;
590         startRep["objarr"] = objarr;
591
592         // Encode/decode
593         OC::MessageContainer mc1;
594         mc1.addRepresentation(startRep);
595
596         OCRepPayload* cstart = mc1.getPayload();
597         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
598
599         uint8_t* cborData;
600         size_t cborSize;
601         OCPayload* cparsed;
602         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
603         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
604                     cborData, cborSize));
605         OCPayloadDestroy((OCPayload*)cstart);
606         OICFree(cborData);
607
608         OC::MessageContainer mc2;
609         mc2.setPayload(cparsed);
610         EXPECT_EQ(1u, mc2.representations().size());
611         const OC::OCRepresentation& r = mc2.representations()[0];
612
613         // Test
614         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
615         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
616         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
617         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
618         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
619
620         EXPECT_EQ(iarr, iarr2);
621         EXPECT_EQ(darr, darr2);
622         EXPECT_EQ(barr, barr2);
623         EXPECT_EQ(strarr, strarr2);
624         EXPECT_EQ(objarr, objarr2);
625         OCPayloadDestroy(cparsed);
626     }
627
628     TEST(RepresentationEncoding, ThreeDVectorsJagged)
629     {
630         // Setup
631         OC::OCRepresentation startRep;
632
633         OC::OCRepresentation subRep1;
634         OC::OCRepresentation subRep2;
635         OC::OCRepresentation subRep3;
636         subRep1.setNULL("NullAttr");
637         subRep1.setValue("IntAttr", 77);
638         subRep2.setValue("DoubleAttr", 3.333);
639         subRep2.setValue("BoolAttr", true);
640         subRep3.setValue("StringAttr", std::string("String attr"));
641
642         std::vector<std::vector<std::vector<int>>> iarr
643             {
644                 {{1,2,3},{4,5,6}},
645                 {{7,8,9},{10,12}},
646                 {{13,14,15},{16,17,18}}
647             };
648         std::vector<std::vector<std::vector<double>>> darr
649             {
650                 {{1.1,2.2,3.3},{4.4,5.5,6.6}},
651                 {{7.7,8.7,9.7},{10.7,12.7}},
652                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}
653             };
654         std::vector<std::vector<std::vector<bool>>> barr
655             {
656                 {{false, true},{true}},
657                 {{false, true},{true, false}}
658             };
659         std::vector<std::vector<std::vector<std::string>>> strarr
660             {
661                 {{"item1", "item2"},{"item3", "item4"}},
662                 {{"item5", "item6"},{"item8"}},
663                 {{"item9", "item10"},{"item11", ""}}
664             };
665         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
666             {
667                 {{subRep1, subRep2},{subRep3, subRep1}},
668                 {{subRep2, subRep3},{subRep2}},
669                 {{subRep3, subRep2}}
670             };
671
672         startRep["iarr"] = iarr;
673         startRep["darr"] = darr;
674         startRep["barr"] = barr;
675         startRep["strarr"] = strarr;
676         startRep["objarr"] = objarr;
677
678         // Encode/decode
679         OC::MessageContainer mc1;
680         mc1.addRepresentation(startRep);
681
682         OCRepPayload* cstart = mc1.getPayload();
683         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
684
685         uint8_t* cborData;
686         size_t cborSize;
687         OCPayload* cparsed;
688         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
689         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
690                     cborData, cborSize));
691         OCPayloadDestroy((OCPayload*)cstart);
692         OICFree(cborData);
693
694         OC::MessageContainer mc2;
695         mc2.setPayload(cparsed);
696         EXPECT_EQ(1u, mc2.representations().size());
697         const OC::OCRepresentation& r = mc2.representations()[0];
698
699         // Test
700         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
701         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
702         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
703         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
704         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
705
706         // Note: due to the way that the CSDK works, all 3d arrays need to be cuboidal.
707         // Since std::vector doesn't require this, items received on the other side end up
708         // being backfilled.  This section removes the backfilling
709         iarr2[1][1].pop_back();
710         darr2[1][1].pop_back();
711         barr2[0][1].pop_back();
712         strarr2[1][1].pop_back();
713         objarr2[1][1].pop_back();
714         objarr2[2].pop_back();
715
716         EXPECT_EQ(iarr, iarr2);
717         EXPECT_EQ(darr, darr2);
718         EXPECT_EQ(barr, barr2);
719         EXPECT_EQ(strarr, strarr2);
720         EXPECT_EQ(objarr, objarr2);
721         OCPayloadDestroy(cparsed);
722     }
723
724     TEST(DiscoveryRTandIF, SingleItemNormal)
725     {
726         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
727         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
728         payload->sid = OICStrdup(sid1);
729         payload->resources = resource;
730
731         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem"));
732         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem"));
733
734         resource->uri = OICStrdup("/uri/thing");
735
736         uint8_t* cborData;
737         size_t cborSize;
738         OCPayload* cparsed;
739
740         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
741         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
742                     cborData, cborSize));
743
744         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
745         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
746
747         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
748         EXPECT_EQ(NULL, parsedResource->next);
749         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
750         EXPECT_EQ(NULL, parsedResource->types->next);
751         EXPECT_EQ(NULL, parsedResource->interfaces->next);
752         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
753
754         OICFree(cborData);
755         OCPayloadDestroy(cparsed);
756         OCDiscoveryPayloadDestroy(payload);
757     }
758
759     TEST(DiscoveryRTandIF, SingleItemFrontTrim)
760     {
761         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
762         payload->sid = OICStrdup(sid1);
763         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
764         payload->resources = resource;
765
766         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem"));
767         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem"));
768         resource->uri = OICStrdup("/uri/thing");
769
770         uint8_t* cborData;
771         size_t cborSize;
772         OCPayload* cparsed;
773
774         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
775         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
776                     cborData, cborSize));
777
778         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
779         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
780
781         EXPECT_EQ(NULL, parsedResource->next);
782         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
783         EXPECT_EQ(NULL, parsedResource->types->next);
784         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
785         EXPECT_EQ(NULL, parsedResource->interfaces->next);
786         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
787
788         OICFree(cborData);
789         OCPayloadDestroy(cparsed);
790         OCDiscoveryPayloadDestroy(payload);
791     }
792
793     TEST(DiscoveryRTandIF, SingleItemBackTrim)
794     {
795         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
796         payload->sid = OICStrdup(sid1);
797         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
798         payload->resources = resource;
799
800         OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem    ");
801         OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem    ");
802         resource->uri = OICStrdup("/uri/thing");
803
804         uint8_t* cborData;
805         size_t cborSize;
806         OCPayload* cparsed;
807
808         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
809         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
810                     cborData, cborSize));
811
812         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
813         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
814
815         EXPECT_EQ(NULL, parsedResource->next);
816         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
817         EXPECT_EQ(NULL, parsedResource->types->next);
818         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
819         EXPECT_EQ(NULL, parsedResource->interfaces->next);
820         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
821
822         OICFree(cborData);
823         OCPayloadDestroy(cparsed);
824         OCDiscoveryPayloadDestroy(payload);
825     }
826     TEST(DiscoveryRTandIF, SingleItemBothTrim)
827     {
828         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
829         payload->sid = OICStrdup(sid1);
830         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
831         payload->resources = resource;
832
833         OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem    ");
834         OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem     ");
835         resource->uri = OICStrdup("/uri/thing");
836
837         uint8_t* cborData;
838         size_t cborSize;
839         OCPayload* cparsed;
840
841         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
842         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
843                     cborData, cborSize));
844
845         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
846         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
847
848         EXPECT_EQ(NULL, parsedResource->next);
849         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
850         EXPECT_EQ(NULL, parsedResource->types->next);
851         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
852         EXPECT_EQ(NULL, parsedResource->interfaces->next);
853         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
854
855         OICFree(cborData);
856         OCPayloadDestroy(cparsed);
857         OCDiscoveryPayloadDestroy(payload);
858     }
859     TEST(DiscoveryRTandIF, MultiItemsNormal)
860     {
861         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
862         payload->sid = OICStrdup(sid1);
863         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
864         payload->resources = resource;
865
866         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem");
867         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem");
868         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem");
869         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem");
870         resource->uri = OICStrdup("/uri/thing");
871
872         uint8_t* cborData;
873         size_t cborSize;
874         OCPayload* cparsed;
875
876         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
877         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
878                     cborData, cborSize));
879
880         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
881         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
882
883         EXPECT_EQ(NULL, parsedResource->next);
884         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
885         EXPECT_EQ(NULL, parsedResource->types->next->next);
886         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
887         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
888         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
889         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
890         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
891
892         OICFree(cborData);
893         OCPayloadDestroy(cparsed);
894         OCDiscoveryPayloadDestroy(payload);
895     }
896     TEST(DiscoveryRTandIF, MultiItemExtraLeadSpaces)
897     {
898         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
899         payload->sid = OICStrdup(sid1);
900         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
901         payload->resources = resource;
902
903         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem");
904         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem");
905         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem");
906         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem");
907         resource->uri = OICStrdup("/uri/thing");
908
909         uint8_t* cborData;
910         size_t cborSize;
911         OCPayload* cparsed;
912
913         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
914         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
915                     cborData, cborSize));
916
917         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
918         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
919
920         EXPECT_EQ(NULL, parsedResource->next);
921         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
922         EXPECT_EQ(NULL, parsedResource->types->next->next);
923         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
924         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
925         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
926         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
927         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
928
929         OICFree(cborData);
930         OCPayloadDestroy(cparsed);
931         OCDiscoveryPayloadDestroy(payload);
932     }
933     TEST(DiscoveryRTandIF, MultiItemExtraTrailSpaces)
934     {
935         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
936         payload->sid = OICStrdup(sid1);
937         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
938         payload->resources = resource;
939
940         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem  ");
941         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem  ");
942         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem  ");
943         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem  ");
944         resource->uri = OICStrdup("/uri/thing");
945
946         uint8_t* cborData;
947         size_t cborSize;
948         OCPayload* cparsed;
949
950         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
951         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
952                     cborData, cborSize));
953
954         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
955         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
956
957         EXPECT_EQ(NULL, parsedResource->next);
958         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
959         EXPECT_EQ(NULL, parsedResource->types->next->next);
960         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
961         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
962         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
963         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
964         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
965
966         OICFree(cborData);
967         OCPayloadDestroy(cparsed);
968         OCDiscoveryPayloadDestroy(payload);
969     }
970     TEST(DiscoveryRTandIF, MultiItemBothSpaces)
971     {
972         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
973         payload->sid = OICStrdup(sid1);
974         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
975         payload->resources = resource;
976
977         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem  ");
978         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem  ");
979         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem  ");
980         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem  ");
981         resource->uri = OICStrdup("/uri/thing");
982
983         uint8_t* cborData;
984         size_t cborSize;
985         OCPayload* cparsed;
986
987         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
988         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
989                     cborData, cborSize));
990
991         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
992         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
993
994         EXPECT_EQ(NULL, parsedResource->next);
995         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
996         EXPECT_EQ(NULL, parsedResource->types->next->next);
997         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
998         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
999         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1000         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1001         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1002
1003         OICFree(cborData);
1004         OCPayloadDestroy(cparsed);
1005         OCDiscoveryPayloadDestroy(payload);
1006     }
1007     TEST(RepresentationEncodingRTandIF, SingleItemNormal)
1008     {
1009         OCRepPayload* payload = OCRepPayloadCreate();
1010         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1011         OCRepPayloadAddInterface(payload, "if.firstitem");
1012
1013         uint8_t* cborData;
1014         size_t cborSize;
1015         OCPayload* cparsed;
1016
1017         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1018         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1019                     cborData, cborSize));
1020
1021         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1022
1023         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1024         EXPECT_EQ(NULL, parsedPayload->types->next);
1025         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1026         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1027
1028         OICFree(cborData);
1029         OCRepPayloadDestroy(payload);
1030         OCPayloadDestroy(cparsed);
1031     }
1032     TEST(RepresentationEncodingRTandIF, SingleItemFrontTrim)
1033     {
1034         OCRepPayload* payload = OCRepPayloadCreate();
1035         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1036         OCRepPayloadAddInterface(payload, "  if.firstitem");
1037
1038         uint8_t* cborData;
1039         size_t cborSize;
1040         OCPayload* cparsed;
1041
1042         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1043         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1044                     cborData, cborSize));
1045
1046         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1047
1048         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1049         EXPECT_EQ(NULL, parsedPayload->types->next);
1050         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1051         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1052
1053
1054         OICFree(cborData);
1055         OCRepPayloadDestroy(payload);
1056         OCPayloadDestroy(cparsed);
1057     }
1058     TEST(RepresentationEncodingRTandIF, SingleItemBackTrim)
1059     {
1060         OCRepPayload* payload = OCRepPayloadCreate();
1061         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1062         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1063
1064         uint8_t* cborData;
1065         size_t cborSize;
1066         OCPayload* cparsed;
1067
1068         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1069         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1070                     cborData, cborSize));
1071
1072         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1073
1074         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1075         EXPECT_EQ(NULL, parsedPayload->types->next);
1076         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1077         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1078
1079
1080         OICFree(cborData);
1081         OCRepPayloadDestroy(payload);
1082         OCPayloadDestroy(cparsed);
1083     }
1084     TEST(RepresentationEncodingRTandIF, SingleItemBothTrim)
1085     {
1086         OCRepPayload* payload = OCRepPayloadCreate();
1087         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1088         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1089
1090         uint8_t* cborData;
1091         size_t cborSize;
1092         OCPayload* cparsed;
1093
1094         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1095         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1096                     cborData, cborSize));
1097
1098         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1099
1100         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1101         EXPECT_EQ(NULL, parsedPayload->types->next);
1102         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1103         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1104
1105
1106         OICFree(cborData);
1107         OCRepPayloadDestroy(payload);
1108         OCPayloadDestroy(cparsed);
1109     }
1110     TEST(RepresentationEncodingRTandIF, MultiItemsNormal)
1111     {
1112         OCRepPayload* payload = OCRepPayloadCreate();
1113         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1114         OCRepPayloadAddResourceType(payload, "rt.seconditem");
1115         OCRepPayloadAddInterface(payload, "if.firstitem");
1116         OCRepPayloadAddInterface(payload, "if.seconditem");
1117
1118         uint8_t* cborData;
1119         size_t cborSize;
1120         OCPayload* cparsed;
1121
1122         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1123         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1124                     cborData, cborSize));
1125
1126         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1127
1128         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1129         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1130         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1131         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1132         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1133         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1134
1135
1136         OICFree(cborData);
1137         OCRepPayloadDestroy(payload);
1138         OCPayloadDestroy(cparsed);
1139     }
1140     TEST(RepresentationEncodingRTandIF, MultiItemExtraLeadSpaces)
1141     {
1142         OCRepPayload* payload = OCRepPayloadCreate();
1143         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1144         OCRepPayloadAddResourceType(payload, "  rt.seconditem");
1145         OCRepPayloadAddInterface(payload, "  if.firstitem");
1146         OCRepPayloadAddInterface(payload, "  if.seconditem");
1147
1148         uint8_t* cborData;
1149         size_t cborSize;
1150         OCPayload* cparsed;
1151
1152         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1153         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1154                     cborData, cborSize));
1155
1156         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1157
1158         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1159         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1160         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1161         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1162         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1163         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1164
1165
1166         OICFree(cborData);
1167         OCRepPayloadDestroy(payload);
1168         OCPayloadDestroy(cparsed);
1169     }
1170     TEST(RepresentationEncodingRTandIF, MultiItemExtraTrailSpaces)
1171     {
1172         OCRepPayload* payload = OCRepPayloadCreate();
1173         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1174         OCRepPayloadAddResourceType(payload, "rt.seconditem  ");
1175         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1176         OCRepPayloadAddInterface(payload, "if.seconditem  ");
1177
1178         uint8_t* cborData;
1179         size_t cborSize;
1180         OCPayload* cparsed;
1181
1182         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1183         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1184                     cborData, cborSize));
1185
1186         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1187
1188         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1189         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1190         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1191         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1192         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1193         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1194
1195
1196         OICFree(cborData);
1197         OCRepPayloadDestroy(payload);
1198         OCPayloadDestroy(cparsed);
1199     }
1200     TEST(RepresentationEncodingRTandIF, MultiItemExtraMiddleSpaces)
1201     {
1202         OCRepPayload* payload = OCRepPayloadCreate();
1203         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1204         OCRepPayloadAddResourceType(payload, "  rt.seconditem  ");
1205         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1206         OCRepPayloadAddInterface(payload, "  if.seconditem  ");
1207
1208         uint8_t* cborData;
1209         size_t cborSize;
1210         OCPayload* cparsed;
1211
1212         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1213         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1214                     cborData, cborSize));
1215
1216         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1217
1218         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1219         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1220         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1221         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1222         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1223         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1224
1225
1226         OICFree(cborData);
1227         OCRepPayloadDestroy(payload);
1228         OCPayloadDestroy(cparsed);
1229     }
1230     TEST(RepresentationEncodingRTandIF, TestPayloadContents)
1231     {
1232         OC::OCRepresentation subRep1;
1233         std::vector<std::string> types;
1234         types.push_back("rt.firstitem");
1235         std::vector<std::string> interfaces;
1236         interfaces.push_back("if.firstitem");
1237         subRep1.setResourceTypes(types);
1238         subRep1.setResourceInterfaces(interfaces);
1239         subRep1.setNULL("NullAttr");
1240         subRep1.setValue("IntAttr", 77);
1241         subRep1.setValue("DoubleAttr", 3.333);
1242         subRep1.setValue("BoolAttr", true);
1243         subRep1.setValue("StringAttr", std::string("String attr"));
1244
1245         OC::MessageContainer mc1;
1246         mc1.addRepresentation(subRep1);
1247
1248         OCRepPayload *repPayload = mc1.getPayload();
1249         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, repPayload->base.type);
1250
1251         uint8_t *cborData = NULL;
1252         size_t cborSize = 0;
1253         OCPayload *cparsed = NULL;
1254
1255         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)repPayload, &cborData, &cborSize));
1256         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1257                     cborData, cborSize));
1258
1259         OCRepPayload *parsedPayload = (OCRepPayload *)cparsed;
1260         EXPECT_EQ(NULL, parsedPayload->uri);
1261         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1262         EXPECT_EQ(NULL, parsedPayload->types->next);
1263         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1264         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1265
1266         // To make sure rt and if are not duplicated.
1267         EXPECT_STREQ("BoolAttr", parsedPayload->values->name);
1268         EXPECT_EQ(true, parsedPayload->values->b);
1269         EXPECT_EQ(OCREP_PROP_BOOL, parsedPayload->values->type);
1270         parsedPayload->values = parsedPayload->values->next;
1271
1272         EXPECT_STREQ("DoubleAttr", parsedPayload->values->name);
1273         EXPECT_EQ(OCREP_PROP_DOUBLE, parsedPayload->values->type);
1274         EXPECT_EQ(3.3330000000000002, parsedPayload->values->d);
1275         parsedPayload->values = parsedPayload->values->next;
1276
1277         EXPECT_STREQ("IntAttr", parsedPayload->values->name);
1278         EXPECT_EQ(77, parsedPayload->values->i);
1279         EXPECT_EQ(OCREP_PROP_INT, parsedPayload->values->type);
1280         parsedPayload->values = parsedPayload->values->next;
1281
1282         EXPECT_STREQ("NullAttr", parsedPayload->values->name);
1283         EXPECT_EQ(OCREP_PROP_NULL, parsedPayload->values->type);
1284         parsedPayload->values = parsedPayload->values->next;
1285
1286         EXPECT_STREQ("StringAttr", parsedPayload->values->name);
1287         EXPECT_STREQ("String attr", parsedPayload->values->str);
1288         EXPECT_EQ(OCREP_PROP_STRING, parsedPayload->values->type);
1289         parsedPayload->values = parsedPayload->values->next;
1290
1291         EXPECT_EQ(NULL, parsedPayload->values);
1292
1293         OICFree(cborData);
1294         OCRepPayloadDestroy(repPayload);
1295         OCPayloadDestroy(cparsed);
1296     }
1297 }