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