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