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