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