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