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