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