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