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