Revert "[CONPRO-1337] Disabled Presence Feature"
[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 bool operator==(const OCByteString& lhs, const OCByteString& rhs)
33 {
34     bool result = (lhs.len == rhs.len);
35     if (result)
36     {
37         result = (memcmp(lhs.bytes, rhs.bytes, lhs.len) == 0);
38     }
39     return result;
40 }
41
42 namespace OC
43 {
44     bool operator==(const OC::NullType&, const OC::NullType&)
45     {
46         return true;
47     }
48
49     bool operator==(const OC::OCRepresentation& lhs, const OC::OCRepresentation& rhs)
50     {
51         return lhs.getUri() == rhs.getUri() &&
52             lhs.getChildren() == rhs.getChildren() &&
53             lhs.getResourceInterfaces() == rhs.getResourceInterfaces() &&
54             lhs.getResourceTypes() == rhs.getResourceTypes() &&
55             lhs.m_values == rhs.m_values;
56     }
57 }
58 // these tests validate the OCRepresentation->OCPayload, OCPayload->CBOR,
59 // CBOR->OCPayload and OCPayload->OCRepresentation conversions
60 namespace OCRepresentationEncodingTest
61 {
62     static const char *sid1;
63     // Device Payloads
64     TEST(DeviceDiscoveryEncoding, Normal)
65     {
66         sid1 = OCGetServerInstanceIDString();
67         const char devicename1[] = "device name";
68         OCRepPayload *device = OCRepPayloadCreate();
69         EXPECT_TRUE(device);
70         EXPECT_TRUE(OCRepPayloadAddResourceType(device, OC_RSRVD_RESOURCE_TYPE_DEVICE));
71         EXPECT_TRUE(OCRepPayloadAddResourceType(device, "oic.d.tv"));
72         EXPECT_TRUE(OCRepPayloadSetPropString(device, OC_RSRVD_DEVICE_ID, sid1));
73         EXPECT_TRUE(OCRepPayloadSetPropString(device, OC_RSRVD_DEVICE_NAME, devicename1));
74         EXPECT_TRUE(OCRepPayloadSetPropString(device, OC_RSRVD_SPEC_VERSION, OC_SPEC_VERSION));
75         EXPECT_TRUE(OCRepPayloadSetPropString(device, "x.org.iotivity.newproperty", "value"));
76
77         size_t dim[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
78         char **dt = (char **)OICMalloc(sizeof(char *) * 1);
79         EXPECT_TRUE(dt);
80         dt[0] = OICStrdup(OC_DATA_MODEL_VERSION);
81         EXPECT_TRUE(OCRepPayloadSetStringArray(device, OC_RSRVD_DATA_MODEL_VERSION, (const char **)dt, dim));
82         OICFree(dt[0]);
83         OICFree(dt);
84
85         uint8_t* cborData;
86         size_t cborSize;
87         OCPayload* parsedDevice;
88         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)device, &cborData, &cborSize));
89         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedDevice, PAYLOAD_TYPE_REPRESENTATION, cborData, cborSize));
90         OICFree(cborData);
91
92         OCRepPayload *parsedRep = (OCRepPayload *)parsedDevice;
93         char *value = NULL;
94         EXPECT_TRUE(OCRepPayloadGetPropString(parsedRep, OC_RSRVD_DEVICE_ID, &value));
95         EXPECT_STREQ(sid1, value);
96         OICFree(value);
97         EXPECT_TRUE(OCRepPayloadGetPropString(parsedRep, OC_RSRVD_DEVICE_NAME, &value));
98         EXPECT_STREQ(devicename1, value);
99         OICFree(value);
100         EXPECT_TRUE(OCRepPayloadGetPropString(parsedRep, OC_RSRVD_SPEC_VERSION, &value));
101         EXPECT_STREQ(OC_SPEC_VERSION, value);
102         OICFree(value);
103         EXPECT_TRUE(OCRepPayloadGetPropString(device, "x.org.iotivity.newproperty", &value));
104         EXPECT_STREQ("value", value);
105         OICFree(value);
106         char **dmv = NULL;
107         EXPECT_TRUE(OCRepPayloadGetStringArray(parsedRep, OC_RSRVD_DATA_MODEL_VERSION, &dmv, dim));
108         EXPECT_STREQ(OC_DATA_MODEL_VERSION, dmv[0]);
109         OICFree(dmv[0]);
110         OICFree(dmv);
111         EXPECT_STREQ("oic.wk.d", parsedRep->types->value);
112         EXPECT_STREQ("oic.d.tv", parsedRep->types->next->value);
113         EXPECT_EQ(device->base.type, parsedRep->base.type);
114
115         OCPayloadDestroy((OCPayload*)device);
116
117         OC::MessageContainer mc1;
118         mc1.setPayload(parsedDevice);
119         EXPECT_EQ(1u, mc1.representations().size());
120         const OC::OCRepresentation &r1 = mc1.representations()[0];
121         EXPECT_STREQ(sid1, r1.getValue<std::string>(OC_RSRVD_DEVICE_ID).c_str());
122         EXPECT_STREQ(devicename1, r1.getValue<std::string>(OC_RSRVD_DEVICE_NAME).c_str());
123         EXPECT_STREQ(OC_SPEC_VERSION, r1.getValue<std::string>(OC_RSRVD_SPEC_VERSION).c_str());
124         EXPECT_STREQ("value", r1.getValue<std::string>("x.org.iotivity.newproperty").c_str());
125         std::vector<std::string> dmv2 = r1.getValue<std::vector<std::string>>(OC_RSRVD_DATA_MODEL_VERSION);
126         EXPECT_STREQ(OC_DATA_MODEL_VERSION, dmv2[0].c_str());
127
128         OCPayloadDestroy(parsedDevice);
129
130         device = OCRepPayloadCreate();
131         EXPECT_TRUE(device);
132         EXPECT_TRUE(OCRepPayloadAddResourceType(device, OC_RSRVD_RESOURCE_TYPE_DEVICE));
133         EXPECT_TRUE(OCRepPayloadAddResourceType(device, "oic.d.tv"));
134         EXPECT_TRUE(OCRepPayloadSetPropString(device, OC_RSRVD_DEVICE_NAME, devicename1));
135         EXPECT_TRUE(OCRepPayloadSetPropString(device, OC_RSRVD_DEVICE_ID, sid1));
136         EXPECT_TRUE(OCRepPayloadSetPropString(device, OC_RSRVD_SPEC_VERSION, OC_SPEC_VERSION));
137         size_t dim1[MAX_REP_ARRAY_DEPTH] = {2, 0, 0};
138         char **dt1 = (char **)OICMalloc(sizeof(char *) * 2);
139         EXPECT_TRUE(dt1);
140         dt1[0] = OICStrdup("res.1.1.0");
141         dt1[1] = OICStrdup("sh.1.1.0");
142         OCRepPayloadSetStringArray(device, OC_RSRVD_DATA_MODEL_VERSION, (const char**)dt1, dim1);
143         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)device, &cborData, &cborSize));
144         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedDevice, PAYLOAD_TYPE_REPRESENTATION, cborData, cborSize));
145         OICFree(cborData);
146         OICFree(dt1[0]);
147         OICFree(dt1[1]);
148         OICFree(dt1);
149         char **dmv1 = NULL;
150         parsedRep = (OCRepPayload *)parsedDevice;
151         EXPECT_TRUE(OCRepPayloadGetStringArray(parsedRep, OC_RSRVD_DATA_MODEL_VERSION, &dmv1, dim));
152         EXPECT_STREQ("res.1.1.0", dmv1[0]);
153         EXPECT_STREQ("sh.1.1.0", dmv1[1]);
154         OICFree(dmv1[0]);
155         OICFree(dmv1[1]);
156         OICFree(dmv1);
157         OCPayloadDestroy((OCPayload *)device);
158         OC::MessageContainer mc2;
159         mc2.setPayload(parsedDevice);
160         EXPECT_EQ(1u, mc2.representations().size());
161         const OC::OCRepresentation r2 = mc2.representations()[0];
162         std::vector<std::string> dmv3 = r2.getValue<std::vector<std::string>>(OC_RSRVD_DATA_MODEL_VERSION);
163         EXPECT_STREQ("res.1.1.0", dmv3[0].c_str());
164         EXPECT_STREQ("sh.1.1.0", dmv3[1].c_str());
165         OCPayloadDestroy(parsedDevice);
166     }
167
168     // Platform Payloads
169     TEST(PlatformDiscoveryEncoding, Normal)
170     {
171         static char pfid1[] = "646F6F72-4465-7669-6365-555549443030";
172         static char mfgnm1[] = "mfgnm";
173         static char mfgurl1[] = "http://www.iotivity.org";
174         static char modelnum1[] = "modelnum";
175         static char dom1[] = "dom";
176         static char pfver1[] = "pfver";
177         static char osver1[] = "osver";
178         static char hwver1[] = "hwver";
179         static char fwver1[] = "fwver";
180         static char url1[] = "http://www.iotivity.org";
181         static char time1[] = "20161122T143938Z";
182         static char vid1[] = "Manufacturer Freeform Text";
183         OCRepPayload *platform = OCRepPayloadCreate();
184         EXPECT_TRUE(platform != NULL);
185         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, ((OCPayload*)platform)->type);
186         EXPECT_TRUE(OCRepPayloadAddResourceType(platform, (char *)OC_RSRVD_RESOURCE_TYPE_PLATFORM));
187         EXPECT_TRUE(OCRepPayloadAddInterface(platform, (char *)OC_RSRVD_INTERFACE_DEFAULT));
188         EXPECT_TRUE(OCRepPayloadAddInterface(platform, (char *)OC_RSRVD_INTERFACE_READ));
189         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_PLATFORM_ID, pfid1));
190         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_MFG_NAME, mfgnm1));
191         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_MFG_URL, mfgurl1));
192         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_MODEL_NUM, modelnum1));
193         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_MFG_DATE, dom1));
194         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_OS_VERSION, osver1));
195         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_PLATFORM_VERSION, pfver1));
196         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_HARDWARE_VERSION, hwver1));
197         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_FIRMWARE_VERSION, fwver1));
198         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_SUPPORT_URL, url1));
199         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_SYSTEM_TIME, time1));
200         EXPECT_TRUE(OCRepPayloadSetPropString(platform, OC_RSRVD_VID, vid1));
201
202
203         uint8_t* cborData;
204         size_t cborSize;
205         OCPayload* parsedPlatform = NULL;
206         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)platform, &cborData, &cborSize));
207         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&parsedPlatform, PAYLOAD_TYPE_REPRESENTATION, cborData, cborSize));
208         OICFree(cborData);
209
210         OCRepPayload *platform1 = (OCRepPayload *)parsedPlatform;
211         EXPECT_EQ(platform->base.type, platform1->base.type);
212         char *value = NULL;
213         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_PLATFORM_ID, &value));
214         EXPECT_STREQ(pfid1, value);
215         OICFree(value);
216
217         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_MFG_NAME, &value));
218         EXPECT_STREQ(mfgnm1, value);
219         OICFree(value);
220
221         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_MFG_URL, &value));
222         EXPECT_STREQ(mfgurl1, value);
223         OICFree(value);
224
225         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_MODEL_NUM, &value));
226         EXPECT_STREQ(modelnum1, value);
227         OICFree(value);
228
229         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_MFG_DATE, &value));
230         EXPECT_STREQ(dom1, value);
231         OICFree(value);
232
233         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_OS_VERSION, &value));
234         EXPECT_STREQ(osver1, value);
235         OICFree(value);
236
237         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_PLATFORM_VERSION, &value));
238         EXPECT_STREQ(pfver1, value);
239         OICFree(value);
240
241         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_HARDWARE_VERSION, &value));
242         EXPECT_STREQ(hwver1, value);
243         OICFree(value);
244
245         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_FIRMWARE_VERSION, &value));
246         EXPECT_STREQ(fwver1, value);
247         OICFree(value);
248
249         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_SUPPORT_URL, &value));
250         EXPECT_STREQ(url1, value);
251         OICFree(value);
252
253         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_SYSTEM_TIME, &value));
254         EXPECT_STREQ(time1, value);
255         OICFree(value);
256
257         EXPECT_TRUE(OCRepPayloadGetPropString(platform1, OC_RSRVD_VID, &value));
258         EXPECT_STREQ(vid1, value);
259         OICFree(value);
260
261         EXPECT_STREQ(platform1->types->value, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
262         EXPECT_STREQ(platform1->interfaces->value, OC_RSRVD_INTERFACE_DEFAULT);
263         EXPECT_STREQ(platform1->interfaces->next->value, OC_RSRVD_INTERFACE_READ);
264
265         OC::MessageContainer mc;
266         mc.setPayload(parsedPlatform);
267         EXPECT_EQ(1u, mc.representations().size());
268         const OC::OCRepresentation& r = mc.representations()[0];
269         EXPECT_STREQ(pfid1, r.getValue<std::string>(OC_RSRVD_PLATFORM_ID).c_str());
270         EXPECT_STREQ(mfgnm1, r.getValue<std::string>(OC_RSRVD_MFG_NAME).c_str());
271         EXPECT_STREQ(mfgurl1, r.getValue<std::string>(OC_RSRVD_MFG_URL).c_str());
272         EXPECT_STREQ(modelnum1, r.getValue<std::string>(OC_RSRVD_MODEL_NUM).c_str());
273         EXPECT_STREQ(dom1, r.getValue<std::string>(OC_RSRVD_MFG_DATE).c_str());
274         EXPECT_STREQ(pfver1, r.getValue<std::string>(OC_RSRVD_PLATFORM_VERSION).c_str());
275         EXPECT_STREQ(osver1, r.getValue<std::string>(OC_RSRVD_OS_VERSION).c_str());
276         EXPECT_STREQ(hwver1, r.getValue<std::string>(OC_RSRVD_HARDWARE_VERSION).c_str());
277         EXPECT_STREQ(fwver1, r.getValue<std::string>(OC_RSRVD_FIRMWARE_VERSION).c_str());
278         EXPECT_STREQ(url1, r.getValue<std::string>(OC_RSRVD_SUPPORT_URL).c_str());
279         EXPECT_STREQ(time1, r.getValue<std::string>(OC_RSRVD_SYSTEM_TIME).c_str());
280         EXPECT_STREQ(vid1, r.getValue<std::string>(OC_RSRVD_VID).c_str());
281
282         OCPayloadDestroy((OCPayload *)platform);
283         OCPayloadDestroy((OCPayload *)platform1);
284     }
285
286     TEST(PresencePayload, Normal)
287     {
288         static const char uri1[] = "/testuri";
289         uint32_t maxAge = 0;
290         uint32_t sequenceNumber = 0;
291         OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
292         OCPresencePayload *presence = OCPresencePayloadCreate(sequenceNumber, maxAge, trigger, uri1);
293
294         uint8_t* cborData;
295         size_t cborSize;
296         OCPayload* cparsed;
297         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)presence, &cborData, &cborSize));
298         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_PRESENCE,
299                     cborData, cborSize));
300         OCPayloadDestroy((OCPayload*)presence);
301         OICFree(cborData);
302
303         OCPresencePayload* parsed = ((OCPresencePayload*)cparsed);
304         EXPECT_EQ(sequenceNumber, parsed->sequenceNumber);
305         EXPECT_EQ(maxAge, parsed->maxAge);
306         EXPECT_EQ(trigger, parsed->trigger);
307         EXPECT_STREQ(uri1, parsed->resourceType);
308
309         OCPayloadDestroy(cparsed);
310     }
311     // Representation Payloads
312     TEST(RepresentationEncoding, BaseAttributeTypes)
313     {
314         OC::OCRepresentation startRep;
315         startRep.setNULL("NullAttr");
316         startRep.setValue("IntAttr", 77);
317         startRep.setValue("DoubleAttr", 3.333);
318         startRep.setValue("BoolAttr", true);
319         startRep.setValue("StringAttr", std::string("String attr"));
320
321         uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
322                             0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
323                            };
324         OCByteString byteString = {binval, sizeof(binval)};
325         startRep.setValue("ByteStringAttr", byteString);
326
327         OC::MessageContainer mc1;
328         mc1.addRepresentation(startRep);
329
330         OCRepPayload* cstart = mc1.getPayload();
331         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
332
333         uint8_t* cborData;
334         size_t cborSize;
335         OCPayload* cparsed;
336         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
337         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
338                     cborData, cborSize));
339         OCPayloadDestroy((OCPayload*)cstart);
340         OICFree(cborData);
341
342         OC::MessageContainer mc2;
343         mc2.setPayload(cparsed);
344         EXPECT_EQ(1u, mc2.representations().size());
345         const OC::OCRepresentation& r = mc2.representations()[0];
346
347         EXPECT_TRUE(r.isNULL("NullAttr"));
348         EXPECT_EQ(77, r.getValue<int>("IntAttr"));
349         EXPECT_EQ(3.333, r.getValue<double>("DoubleAttr"));
350         EXPECT_EQ(true, r.getValue<bool>("BoolAttr"));
351         EXPECT_STREQ("String attr", r.getValue<std::string>("StringAttr").c_str());
352         const char *expectedByteString = "\\x1\\x2\\x3\\x4\\x5\\x6\\x7\\x8\\x9\\x0\\xa\\xb\\xc\\xd\\xe\\xf";
353         EXPECT_STREQ(expectedByteString, r.getValueToString("ByteStringAttr").c_str());
354
355         OCPayloadDestroy(cparsed);
356     }
357
358     TEST(RepresentationEncoding, RepAttributeEmpty)
359     {
360         OC::OCRepresentation startRep;
361         std::vector<int> iarr {};
362         std::vector<double> darr {};
363         std::vector<bool> barr {};
364         std::vector<std::string> strarr {};
365         std::vector<OC::OCRepresentation> objarr {};
366         std::vector<OCByteString> bytestrarr {{NULL, 0}};
367         startRep.setValue("StringAttr", std::string(""));
368         startRep["iarr"] = iarr;
369         startRep["darr"] = darr;
370         startRep["barr"] = barr;
371         startRep["strarr"] = strarr;
372         startRep["objarr"] = objarr;
373         startRep["bytestrarr"] = bytestrarr;
374         startRep.setValue("StringAttr2", std::string("String attr"));
375
376         OC::MessageContainer mc1;
377         mc1.addRepresentation(startRep);
378         OCRepPayload* cstart = mc1.getPayload();
379         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
380
381         uint8_t *cborData = NULL;
382         size_t cborSize = 0;
383         OCPayload *cparsed = NULL;
384         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
385         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
386                     cborData, cborSize));
387         OCPayloadDestroy((OCPayload*)cstart);
388         OICFree(cborData);
389
390         OC::MessageContainer mc2;
391         mc2.setPayload(cparsed);
392         EXPECT_EQ(1u, mc2.representations().size());
393         const OC::OCRepresentation& r = mc2.representations()[0];
394
395         EXPECT_STREQ("", r.getValue<std::string>("StringAttr").c_str());
396         std::vector<int> iarr2 = r["iarr"];
397         EXPECT_EQ(iarr, iarr2);
398         std::vector<double> darr2 = r["darr"];
399         EXPECT_EQ(darr, darr2);
400         std::vector<bool> barr2 = r["barr"];
401         EXPECT_EQ(barr, barr2);
402         std::vector<std::string> strarr2 = r["strarr"];
403         EXPECT_EQ(strarr, strarr2);
404         std::vector<OC::OCRepresentation> objarr2 = r["objarr"];
405         EXPECT_EQ(objarr, objarr2);
406         std::vector<uint8_t> binAttr = r.getValue<std::vector<uint8_t>>("BinaryAttr");
407         EXPECT_EQ(bytestrarr[0].len, binAttr.size());
408         EXPECT_STREQ("String attr", r.getValue<std::string>("StringAttr2").c_str());
409         OIC_LOG_PAYLOAD(DEBUG, cparsed);
410         OCPayloadDestroy(cparsed);
411     }
412
413     TEST(RepresentationEncoding, RepAttribute)
414     {
415         OC::OCRepresentation startRep;
416         OC::OCRepresentation subRep;
417         subRep.setNULL("NullAttr");
418         subRep.setValue("IntAttr", 77);
419         subRep.setValue("DoubleAttr", 3.333);
420         subRep.setValue("BoolAttr", true);
421         subRep.setValue("StringAttr", std::string("String attr"));
422         std::vector<uint8_t> bin_data {5,3,4,5,6,0,34,2,4,5,6,3};
423         subRep.setValue("BinaryAttr", bin_data);
424         startRep.setValue("Sub", subRep);
425
426         OC::MessageContainer mc1;
427         mc1.addRepresentation(startRep);
428
429         OCRepPayload* cstart = mc1.getPayload();
430         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
431
432         uint8_t* cborData;
433         size_t cborSize;
434         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
435         OCPayload* cparsed;
436         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
437                     cborData, cborSize));
438         OCPayloadDestroy((OCPayload*)cstart);
439         OICFree(cborData);
440
441         OC::MessageContainer mc2;
442         mc2.setPayload(cparsed);
443         EXPECT_EQ(1u, mc2.representations().size());
444         const OC::OCRepresentation& r = mc2.representations()[0];
445
446         OC::OCRepresentation newSubRep = r["Sub"];
447
448         EXPECT_TRUE(newSubRep.isNULL("NullAttr"));
449         EXPECT_EQ(77, newSubRep.getValue<int>("IntAttr"));
450         EXPECT_EQ(3.333, newSubRep.getValue<double>("DoubleAttr"));
451         EXPECT_EQ(true, newSubRep.getValue<bool>("BoolAttr"));
452         EXPECT_STREQ("String attr", newSubRep.getValue<std::string>("StringAttr").c_str());
453         EXPECT_EQ(bin_data,
454                 newSubRep.getValue<std::vector<uint8_t>>("BinaryAttr"));
455         OCPayloadDestroy(cparsed);
456     }
457
458     TEST(RepresentationEncoding, OneDVectors)
459     {
460         // Setup
461         OC::OCRepresentation startRep;
462
463         OC::OCRepresentation subRep1;
464         OC::OCRepresentation subRep2;
465         OC::OCRepresentation subRep3;
466         subRep1.setNULL("NullAttr");
467         subRep1.setValue("IntAttr", 77);
468         subRep2.setValue("DoubleAttr", 3.333);
469         subRep2.setValue("BoolAttr", true);
470         subRep3.setValue("StringAttr", std::string("String attr"));
471
472         std::vector<int> iarr {1,2,3,4,5,6,7,8,9};
473         std::vector<double> darr {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9};
474         std::vector<bool> barr {false, true, false, false, true, true};
475         std::vector<std::string> strarr {"item1", "item2", "item3", "item4"};
476         std::vector<OC::OCRepresentation> objarr {subRep1, subRep2, subRep3};
477
478         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
479         OCByteString byteStringRef1 {binval1, sizeof(binval1)};
480         OCByteString byteString1 {NULL,0};
481         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
482         uint8_t binval2[] = {0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
483         OCByteString byteStringRef2 {binval2, sizeof(binval2)};
484         OCByteString byteString2 {NULL,0};
485         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
486         std::vector<OCByteString> bytestrarrRef {byteStringRef1, byteStringRef2 };
487         std::vector<OCByteString> bytestrarr {byteString1, byteString2 };
488
489         startRep["iarr"] = iarr;
490         startRep["darr"] = darr;
491         startRep["barr"] = barr;
492         startRep["strarr"] = strarr;
493         startRep["objarr"] = objarr;
494         startRep["bytestrarr"] = bytestrarr;
495
496         // Encode/decode
497         OC::MessageContainer mc1;
498         mc1.addRepresentation(startRep);
499
500         OCRepPayload* cstart = mc1.getPayload();
501         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
502
503         uint8_t* cborData;
504         size_t cborSize;
505         OCPayload* cparsed;
506         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
507         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
508                                               cborData, cborSize));
509         OCPayloadDestroy((OCPayload *)cstart);
510         OICFree(cborData);
511
512         OC::MessageContainer mc2;
513         mc2.setPayload(cparsed);
514         EXPECT_EQ(1u, mc2.representations().size());
515         const OC::OCRepresentation &r = mc2.representations()[0];
516
517         // Test
518         std::vector<int> iarr2 = r["iarr"];
519         std::vector<double> darr2 = r["darr"];
520         std::vector<bool> barr2 = r["barr"];
521         std::vector<std::string> strarr2 = r["strarr"];
522         std::vector<OC::OCRepresentation> objarr2 = r["objarr"];
523         std::vector<OCByteString> bytestrarr2 = r["bytestrarr"];
524
525         EXPECT_EQ(iarr, iarr2);
526         EXPECT_EQ(darr, darr2);
527         EXPECT_EQ(barr, barr2);
528         EXPECT_EQ(strarr, strarr2);
529         EXPECT_EQ(objarr, objarr2);
530
531         EXPECT_EQ(bytestrarrRef, bytestrarr2);
532         OCPayloadDestroy(cparsed);
533     }
534
535     TEST(RepresentationEncoding, TwoDVectors)
536     {
537         // Setup
538         OC::OCRepresentation startRep;
539
540         OC::OCRepresentation subRep1;
541         OC::OCRepresentation subRep2;
542         OC::OCRepresentation subRep3;
543         subRep1.setNULL("NullAttr");
544         subRep1.setValue("IntAttr", 77);
545         subRep2.setValue("DoubleAttr", 3.333);
546         subRep2.setValue("BoolAttr", true);
547         subRep3.setValue("StringAttr", std::string("String attr"));
548
549         std::vector<std::vector<int>> iarr {{1,2,3},{4,5,6},{7,8,9}};
550         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{7.7,8.8,9.9}};
551         std::vector<std::vector<bool>> barr {{false, true}, {false, false}, {true, true}};
552         std::vector<std::vector<std::string>> strarr {{"item1", "item2"}, {"item3", "item4"}};
553         std::vector<std::vector<OC::OCRepresentation>> objarr
554         {{subRep1, subRep2, subRep3}, {subRep3, subRep2, subRep1}};
555
556         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4};
557         OCByteString byteStringRef1 {binval1, sizeof(binval1) };
558         OCByteString byteString1 {NULL,0};
559         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
560         uint8_t binval2[] = {0x5, 0x6, 0x7, 0x8};
561         OCByteString byteStringRef2 {binval2, sizeof(binval2) };
562         OCByteString byteString2 {NULL,0};
563         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
564         uint8_t binval3[] = {0x9, 0x0, 0xA, 0xB};
565         OCByteString byteStringRef3 {binval3, sizeof(binval3) };
566         OCByteString byteString3 {NULL,0};
567         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
568         uint8_t binval4[] = {0xC, 0xD, 0xE, 0xF};
569         OCByteString byteStringRef4 {binval4, sizeof(binval4) };
570         OCByteString byteString4 {NULL,0};
571         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
572         std::vector<std::vector<OCByteString>> bytestrarrRef
573         {
574             {byteStringRef1, byteStringRef2}, {byteStringRef3, byteStringRef4}
575         };
576         std::vector<std::vector<OCByteString>> bytestrarr
577         {
578             {byteString1, byteString2}, {byteString3, byteString4}
579         };
580
581         startRep["iarr"] = iarr;
582         startRep["darr"] = darr;
583         startRep["barr"] = barr;
584         startRep["strarr"] = strarr;
585         startRep["objarr"] = objarr;
586         startRep["bytestrarr"] = bytestrarr;
587
588         // Encode/decode
589         OC::MessageContainer mc1;
590         mc1.addRepresentation(startRep);
591
592         OCRepPayload *cstart = mc1.getPayload();
593         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
594
595         uint8_t* cborData;
596         size_t cborSize;
597         OCPayload* cparsed;
598         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
599         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
600                                               cborData, cborSize));
601         OCPayloadDestroy((OCPayload *)cstart);
602         OICFree(cborData);
603
604         OC::MessageContainer mc2;
605         mc2.setPayload(cparsed);
606         EXPECT_EQ(1u, mc2.representations().size());
607         const OC::OCRepresentation &r = mc2.representations()[0];
608
609         // Test
610         std::vector<std::vector<int>> iarr2 = r["iarr"];
611         std::vector<std::vector<double>> darr2 = r["darr"];
612         std::vector<std::vector<bool>> barr2 = r["barr"];
613         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
614         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
615         std::vector<std::vector<OCByteString>> bytestrarr2 = r["bytestrarr"];
616
617         EXPECT_EQ(iarr, iarr2);
618         EXPECT_EQ(darr, darr2);
619         EXPECT_EQ(barr, barr2);
620         EXPECT_EQ(strarr, strarr2);
621         EXPECT_EQ(objarr, objarr2);
622
623         EXPECT_EQ(bytestrarrRef, bytestrarr2);
624
625         OCPayloadDestroy(cparsed);
626     }
627
628     TEST(RepresentationEncoding, TwoDVectorsJagged)
629     {
630         // Setup
631         OC::OCRepresentation startRep;
632
633         OC::OCRepresentation subRep1;
634         OC::OCRepresentation subRep2;
635         OC::OCRepresentation subRep3;
636         subRep1.setNULL("NullAttr");
637         subRep1.setValue("IntAttr", 77);
638         subRep2.setValue("DoubleAttr", 3.333);
639         subRep2.setValue("BoolAttr", true);
640         subRep3.setValue("StringAttr", std::string("String attr"));
641
642         std::vector<std::vector<int>> iarr {{1,2,3},{4,6},{7,8,9}};
643         std::vector<std::vector<double>> darr {{1.1,2.2,3.3},{4.4,5.5,6.6},{8.8,9.9}};
644         std::vector<std::vector<bool>> barr {{false, true}, {false}, {true, true}};
645         std::vector<std::vector<std::string>> strarr {{"item1"}, {"item3", "item4"}};
646         std::vector<std::vector<OC::OCRepresentation>> objarr
647         {{subRep1, subRep3}, {subRep3, subRep2, subRep1}};
648
649         uint8_t binval1[] = {0x1};
650         OCByteString byteStringRef1 {binval1, sizeof(binval1) };
651         OCByteString byteString1 {NULL,0};
652         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
653         uint8_t binval3[] = {0x2, 0x3, 0x4};
654         OCByteString byteStringRef3 {binval3, sizeof(binval3) };
655         OCByteString byteString3 {NULL,0};
656         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
657         uint8_t binval4[] = {0x5, 0x6, 0x7, 0x8};
658         OCByteString byteStringRef4 {binval4, sizeof(binval4) };
659         OCByteString byteString4 {NULL,0};
660         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
661
662         std::vector<std::vector<OCByteString>> bytestrarrRef
663         {
664             {byteStringRef1}, {byteStringRef3, byteStringRef4}
665         };
666
667         std::vector<std::vector<OCByteString>> bytestrarr
668         {
669             {byteString1}, {byteString3, byteString4}
670         };
671
672         startRep["iarr"] = iarr;
673         startRep["darr"] = darr;
674         startRep["barr"] = barr;
675         startRep["strarr"] = strarr;
676         startRep["objarr"] = objarr;
677
678         startRep["bytestrarr"] = bytestrarr;
679
680         EXPECT_STREQ("[[\\x1 ] [\\x2\\x3\\x4 \\x5\\x6\\x7\\x8 ] ]",
681                      startRep.getValueToString("bytestrarr").c_str());
682         // Encode/decode
683         OC::MessageContainer mc1;
684         mc1.addRepresentation(startRep);
685
686         OCRepPayload *cstart = mc1.getPayload();
687         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
688
689         uint8_t *cborData;
690         size_t cborSize;
691         OCPayload *cparsed;
692         OCStackResult result = OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize);
693         EXPECT_EQ(OC_STACK_OK, result);
694         result = OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
695                                 cborData, cborSize);
696         EXPECT_EQ(OC_STACK_OK, result);
697
698         OCPayloadDestroy((OCPayload *)cstart);
699         OICFree(cborData);
700
701         OC::MessageContainer mc2;
702         mc2.setPayload(cparsed);
703         EXPECT_EQ(1u, mc2.representations().size());
704         const OC::OCRepresentation &r = mc2.representations()[0];
705
706         // Test
707         std::vector<std::vector<int>> iarr2 = r["iarr"];
708         std::vector<std::vector<double>> darr2 = r["darr"];
709         std::vector<std::vector<bool>> barr2 = r["barr"];
710         std::vector<std::vector<std::string>> strarr2 = r["strarr"];
711         std::vector<std::vector<OC::OCRepresentation>> objarr2 = r["objarr"];
712
713         std::vector<std::vector<OCByteString>> bytestrarr2 = r["bytestrarr"];
714
715         // Note: due to the way that the CSDK works, all 2d arrays need to be rectangular.
716         // Since std::vector doesn't require this, items received on the other side end up
717         // being backfilled.  This section removes the backfilling
718         iarr2[1].pop_back();
719         darr2[2].pop_back();
720         barr2[1].pop_back();
721         strarr2[0].pop_back();
722         objarr2[0].pop_back();
723         bytestrarr2[0].pop_back();
724
725         EXPECT_EQ(iarr, iarr2);
726         EXPECT_EQ(darr, darr2);
727         EXPECT_EQ(barr, barr2);
728         EXPECT_EQ(strarr, strarr2);
729         EXPECT_EQ(objarr, objarr2);
730         EXPECT_EQ(bytestrarr.size(), bytestrarr2.size());
731         EXPECT_EQ(bytestrarrRef, bytestrarr2);
732
733         OCPayloadDestroy(cparsed);
734     }
735
736     TEST(RepresentationEncoding, ThreeDVectors)
737     {
738         // Setup
739         OC::OCRepresentation startRep;
740
741         OC::OCRepresentation subRep1;
742         OC::OCRepresentation subRep2;
743         OC::OCRepresentation subRep3;
744         subRep1.setNULL("NullAttr");
745         subRep1.setValue("IntAttr", 77);
746         subRep2.setValue("DoubleAttr", 3.333);
747         subRep2.setValue("BoolAttr", true);
748         subRep3.setValue("StringAttr", std::string("String attr"));
749
750         std::vector<std::vector<std::vector<int>>> iarr
751             {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}},{{13,14,15},{16,17,18}}};
752         std::vector<std::vector<std::vector<double>>> darr
753             {{{1.1,2.2,3.3},{4.4,5.5,6.6}},
754                 {{7.7,8.7,9.7},{10.7,11.7,12.7}},
755                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}};
756         std::vector<std::vector<std::vector<bool>>> barr
757             {{{false, true},{true, false}},{{false, true},{true, false}}};
758         std::vector<std::vector<std::vector<std::string>>> strarr
759             {
760                 {{"item1", "item2"},{"item3", "item4"}},
761                 {{"item5", "item6"},{"item7", "item8"}},
762                 {{"item9", "item10"},{"item11", ""}}
763             };
764         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
765             {
766                 {{subRep1, subRep2},{subRep3, subRep1}},
767                 {{subRep2, subRep3},{subRep2, subRep1}},
768                 {{subRep3, subRep2},{subRep1, subRep2}}
769             };
770
771         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4};
772         OCByteString byteStringRef1 {binval1, sizeof(binval1)};
773         OCByteString byteString1 {NULL,0};
774         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
775         uint8_t binval2[] = {0x5, 0x6, 0x7, 0x8};
776         OCByteString byteStringRef2 {binval2, sizeof(binval2)};
777         OCByteString byteString2 {NULL,0};
778         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
779         uint8_t binval3[] = {0x9, 0x0, 0xA, 0xB};
780         OCByteString byteStringRef3 {binval3, sizeof(binval3)};
781         OCByteString byteString3 {NULL,0};
782         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
783         uint8_t binval4[] = {0xC, 0xD, 0xE, 0xF};
784         OCByteString byteStringRef4 {binval4, sizeof(binval4)};
785         OCByteString byteString4 {NULL,0};
786         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
787         uint8_t binval5[] = {0x11, 0x12, 0x13, 0x14};
788         OCByteString byteStringRef5 {binval5, sizeof(binval5)};
789         OCByteString byteString5 {NULL,0};
790         EXPECT_TRUE(OCByteStringCopy(&byteString5, &byteStringRef5));
791         uint8_t binval6[] = {0x15, 0x16, 0x17, 0x18};
792         OCByteString byteStringRef6 {binval6, sizeof(binval6)};
793         OCByteString byteString6 {NULL,0};
794         EXPECT_TRUE(OCByteStringCopy(&byteString6, &byteStringRef6));
795         uint8_t binval7[] = {0x19, 0x10, 0x1A, 0x1B};
796         OCByteString byteStringRef7 {binval7, sizeof(binval7)};
797         OCByteString byteString7 {NULL,0};
798         EXPECT_TRUE(OCByteStringCopy(&byteString7, &byteStringRef7));
799         uint8_t binval8[] = {0x1C, 0x1D, 0x1E, 0x1F};
800         OCByteString byteStringRef8 {binval8, sizeof(binval8)};
801         OCByteString byteString8 {NULL,0};
802         EXPECT_TRUE(OCByteStringCopy(&byteString8, &byteStringRef8));
803         uint8_t binval9[] = {0x21, 0x22, 0x23, 0x24};
804         OCByteString byteStringRef9 {binval9, sizeof(binval9)};
805         OCByteString byteString9 {NULL,0};
806         EXPECT_TRUE(OCByteStringCopy(&byteString9, &byteStringRef9));
807         uint8_t binval10[] = {0x25, 0x26, 0x27, 0x28};
808         OCByteString byteStringRef10 {binval10, sizeof(binval10)};
809         OCByteString byteString10 {NULL,0};
810         EXPECT_TRUE(OCByteStringCopy(&byteString10, &byteStringRef10));
811         uint8_t binval11[] = {0x29, 0x20, 0x2A, 0x2B};
812         OCByteString byteStringRef11 {binval11, sizeof(binval11)};
813         OCByteString byteString11 {NULL,0};
814         EXPECT_TRUE(OCByteStringCopy(&byteString11, &byteStringRef11));
815         uint8_t binval12[] = {0xFF};
816         OCByteString byteStringRef12 {binval12, sizeof(binval12)};
817         OCByteString byteString12 {NULL,0};
818         EXPECT_TRUE(OCByteStringCopy(&byteString12, &byteStringRef12));
819
820         std::vector<std::vector<std::vector<OCByteString>>> bytestrarrRef
821         {
822             {{byteStringRef1, byteStringRef2}, {byteStringRef3, byteStringRef4}},
823             {{byteStringRef5, byteStringRef6}, {byteStringRef7, byteStringRef8}},
824             {{byteStringRef9, byteStringRef10}, {byteStringRef11, byteStringRef12}}
825         };
826
827         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr
828         {
829             {{byteString1, byteString2}, {byteString3, byteString4}},
830             {{byteString5, byteString6}, {byteString7, byteString8}},
831             {{byteString9, byteString10}, {byteString11, byteString12}}
832         };
833
834         startRep["iarr"] = iarr;
835         startRep["darr"] = darr;
836         startRep["barr"] = barr;
837         startRep["strarr"] = strarr;
838         startRep["objarr"] = objarr;
839         startRep["bytestrarr"] = bytestrarr;
840
841         // Encode/decode
842         OC::MessageContainer mc1;
843         mc1.addRepresentation(startRep);
844
845         OCRepPayload *cstart = mc1.getPayload();
846         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
847
848         uint8_t *cborData;
849         size_t cborSize;
850         OCPayload *cparsed;
851         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
852         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
853                                               cborData, cborSize));
854         OCPayloadDestroy((OCPayload *)cstart);
855         OICFree(cborData);
856
857         OC::MessageContainer mc2;
858         mc2.setPayload(cparsed);
859         EXPECT_EQ(1u, mc2.representations().size());
860         const OC::OCRepresentation &r = mc2.representations()[0];
861
862         // Test
863         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
864         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
865         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
866         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
867         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
868         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr2 = r["bytestrarr"];
869
870         EXPECT_EQ(iarr, iarr2);
871         EXPECT_EQ(darr, darr2);
872         EXPECT_EQ(barr, barr2);
873         EXPECT_EQ(strarr, strarr2);
874         EXPECT_EQ(objarr, objarr2);
875         EXPECT_EQ(bytestrarrRef, bytestrarr2);
876         OCPayloadDestroy(cparsed);
877     }
878
879     TEST(RepresentationEncoding, ThreeDVectorsJagged)
880     {
881         // Setup
882         OC::OCRepresentation startRep;
883
884         OC::OCRepresentation subRep1;
885         OC::OCRepresentation subRep2;
886         OC::OCRepresentation subRep3;
887         subRep1.setNULL("NullAttr");
888         subRep1.setValue("IntAttr", 77);
889         subRep2.setValue("DoubleAttr", 3.333);
890         subRep2.setValue("BoolAttr", true);
891         subRep3.setValue("StringAttr", std::string("String attr"));
892
893         std::vector<std::vector<std::vector<int>>> iarr
894             {
895                 {{1,2,3},{4,5,6}},
896                 {{7,8,9},{10,12}},
897                 {{13,14,15},{16,17,18}}
898             };
899         std::vector<std::vector<std::vector<double>>> darr
900             {
901                 {{1.1,2.2,3.3},{4.4,5.5,6.6}},
902                 {{7.7,8.7,9.7},{10.7,12.7}},
903                 {{13.7,14.7,15.7},{16.7,17.7,18.7}}
904             };
905         std::vector<std::vector<std::vector<bool>>> barr
906             {
907                 {{false, true},{true}},
908                 {{false, true},{true, false}}
909             };
910         std::vector<std::vector<std::vector<std::string>>> strarr
911             {
912                 {{"item1", "item2"},{"item3", "item4"}},
913                 {{"item5", "item6"},{"item8"}},
914                 {{"item9", "item10"},{"item11", ""}}
915             };
916         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr
917             {
918                 {{subRep1, subRep2},{subRep3, subRep1}},
919                 {{subRep2, subRep3},{subRep2}},
920                 {{subRep3, subRep2}}
921             };
922
923         uint8_t binval1[] = {0x1, 0x2, 0x3, 0x4};
924         OCByteString byteStringRef1 {binval1, sizeof(binval1)};
925         OCByteString byteString1 {NULL,0};
926         EXPECT_TRUE(OCByteStringCopy(&byteString1, &byteStringRef1));
927         uint8_t binval2[] = {0x5, 0x6, 0x7, 0x8};
928         OCByteString byteStringRef2 {binval2, sizeof(binval2)};
929         OCByteString byteString2 {NULL,0};
930         EXPECT_TRUE(OCByteStringCopy(&byteString2, &byteStringRef2));
931         uint8_t binval3[] = {0x9, 0x0, 0xA, 0xB};
932         OCByteString byteStringRef3 {binval3, sizeof(binval3)};
933         OCByteString byteString3 {NULL,0};
934         EXPECT_TRUE(OCByteStringCopy(&byteString3, &byteStringRef3));
935         uint8_t binval4[] = {0xC, 0xD, 0xE, 0xF};
936         OCByteString byteStringRef4 {binval4, sizeof(binval4)};
937         OCByteString byteString4 {NULL,0};
938         EXPECT_TRUE(OCByteStringCopy(&byteString4, &byteStringRef4));
939         uint8_t binval5[] = {0x11, 0x12, 0x13, 0x14};
940         OCByteString byteStringRef5 {binval5, sizeof(binval5)};
941         OCByteString byteString5 {NULL,0};
942         EXPECT_TRUE(OCByteStringCopy(&byteString5, &byteStringRef5));
943         uint8_t binval6[] = {0x15, 0x16, 0x17, 0x18};
944         OCByteString byteStringRef6 {binval6, sizeof(binval6)};
945         OCByteString byteString6 {NULL,0};
946         EXPECT_TRUE(OCByteStringCopy(&byteString6, &byteStringRef6));
947         uint8_t binval8[] = {0x1C, 0x1D, 0x1E, 0x1F};
948         OCByteString byteStringRef8 {binval8, sizeof(binval8)};
949         OCByteString byteString8 {NULL,0};
950         EXPECT_TRUE(OCByteStringCopy(&byteString8, &byteStringRef8));
951         uint8_t binval9[] = {0x21, 0x22, 0x23, 0x24};
952         OCByteString byteStringRef9 {binval9, sizeof(binval9)};
953         OCByteString byteString9 {NULL,0};
954         EXPECT_TRUE(OCByteStringCopy(&byteString9, &byteStringRef9));
955         uint8_t binval10[] = {0x25, 0x26, 0x27, 0x28};
956         OCByteString byteStringRef10 {binval10, sizeof(binval10)};
957         OCByteString byteString10 {NULL,0};
958         EXPECT_TRUE(OCByteStringCopy(&byteString10, &byteStringRef10));
959         uint8_t binval11[] = {0x29, 0x20, 0x2A, 0x2B};
960         OCByteString byteStringRef11 {binval11, sizeof(binval11)};
961         OCByteString byteString11 {NULL,0};
962         EXPECT_TRUE(OCByteStringCopy(&byteString11, &byteStringRef11));
963         uint8_t binval12[] = {0xFF};
964         OCByteString byteStringRef12 {binval12, sizeof(binval12)};
965         OCByteString byteString12 {NULL,0};
966         EXPECT_TRUE(OCByteStringCopy(&byteString12, &byteStringRef12));
967
968         std::vector<std::vector<std::vector<OCByteString>>> bytestrarrRef
969         {
970             {{byteStringRef1, byteStringRef2}, {byteStringRef3, byteStringRef4}},
971             {{byteStringRef5, byteStringRef6}, {byteStringRef8}},
972             {{byteStringRef9, byteStringRef10}, {byteStringRef11, byteStringRef12}}
973         };
974
975         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr
976         {
977             {{byteString1, byteString2}, {byteString3, byteString4}},
978             {{byteString5, byteString6}, {byteString8}},
979             {{byteString9, byteString10}, {byteString11, byteString12}}
980         };
981
982         startRep["iarr"] = iarr;
983         startRep["darr"] = darr;
984         startRep["barr"] = barr;
985         startRep["strarr"] = strarr;
986         startRep["objarr"] = objarr;
987         startRep["bytestrarr"] = bytestrarr;
988
989         // Encode/decode
990         OC::MessageContainer mc1;
991         mc1.addRepresentation(startRep);
992
993         OCRepPayload *cstart = mc1.getPayload();
994         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
995
996         uint8_t *cborData;
997         size_t cborSize;
998         OCPayload *cparsed;
999         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload *)cstart, &cborData, &cborSize));
1000         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1001                                               cborData, cborSize));
1002         OCPayloadDestroy((OCPayload *)cstart);
1003         OICFree(cborData);
1004
1005         OC::MessageContainer mc2;
1006         mc2.setPayload(cparsed);
1007         EXPECT_EQ(1u, mc2.representations().size());
1008         const OC::OCRepresentation &r = mc2.representations()[0];
1009
1010         // Test
1011         std::vector<std::vector<std::vector<int>>> iarr2 = r["iarr"];
1012         std::vector<std::vector<std::vector<double>>> darr2 = r["darr"];
1013         std::vector<std::vector<std::vector<bool>>> barr2 = r["barr"];
1014         std::vector<std::vector<std::vector<std::string>>> strarr2 = r["strarr"];
1015         std::vector<std::vector<std::vector<OC::OCRepresentation>>> objarr2 = r["objarr"];
1016         std::vector<std::vector<std::vector<OCByteString>>> bytestrarr2 = r["bytestrarr"];
1017
1018         // Note: due to the way that the CSDK works, all 3d arrays need to be cuboidal.
1019         // Since std::vector doesn't require this, items received on the other side end up
1020         // being backfilled.  This section removes the backfilling
1021         iarr2[1][1].pop_back();
1022         darr2[1][1].pop_back();
1023         barr2[0][1].pop_back();
1024         strarr2[1][1].pop_back();
1025         objarr2[1][1].pop_back();
1026         objarr2[2].pop_back();
1027         bytestrarr2[1][1].pop_back();
1028
1029         EXPECT_EQ(iarr, iarr2);
1030         EXPECT_EQ(darr, darr2);
1031         EXPECT_EQ(barr, barr2);
1032         EXPECT_EQ(strarr, strarr2);
1033         EXPECT_EQ(objarr, objarr2);
1034         EXPECT_EQ(bytestrarrRef, bytestrarr2);
1035         OCPayloadDestroy(cparsed);
1036     }
1037
1038     TEST(DiscoveryRTandIF, SingleItemNormal)
1039     {
1040         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1041         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1042         payload->sid = OICStrdup(sid1);
1043         payload->resources = resource;
1044
1045         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem"));
1046         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem"));
1047
1048         resource->uri = OICStrdup("/uri/thing");
1049
1050         uint8_t* cborData;
1051         size_t cborSize;
1052         OCPayload* cparsed;
1053
1054         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1055         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1056                     cborData, cborSize));
1057
1058         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1059         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1060
1061         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1062         EXPECT_EQ(NULL, parsedResource->next);
1063         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1064         EXPECT_EQ(NULL, parsedResource->types->next);
1065         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1066         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1067
1068         OICFree(cborData);
1069         OCPayloadDestroy(cparsed);
1070         OCDiscoveryPayloadDestroy(payload);
1071     }
1072
1073     TEST(DiscoveryRTandIF, SingleItemFrontTrim)
1074     {
1075         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1076         payload->sid = OICStrdup(sid1);
1077         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1078         payload->resources = resource;
1079
1080         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem"));
1081         EXPECT_TRUE(OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem"));
1082         resource->uri = OICStrdup("/uri/thing");
1083
1084         uint8_t* cborData;
1085         size_t cborSize;
1086         OCPayload* cparsed;
1087
1088         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1089         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1090                     cborData, cborSize));
1091
1092         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1093         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1094
1095         EXPECT_EQ(NULL, parsedResource->next);
1096         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1097         EXPECT_EQ(NULL, parsedResource->types->next);
1098         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1099         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1100         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1101
1102         OICFree(cborData);
1103         OCPayloadDestroy(cparsed);
1104         OCDiscoveryPayloadDestroy(payload);
1105     }
1106
1107     TEST(DiscoveryRTandIF, SingleItemBackTrim)
1108     {
1109         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1110         payload->sid = OICStrdup(sid1);
1111         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1112         payload->resources = resource;
1113
1114         OCResourcePayloadAddStringLL(&resource->types, "rt.singleitem    ");
1115         OCResourcePayloadAddStringLL(&resource->interfaces, "if.singleitem    ");
1116         resource->uri = OICStrdup("/uri/thing");
1117
1118         uint8_t* cborData;
1119         size_t cborSize;
1120         OCPayload* cparsed;
1121
1122         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1123         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1124                     cborData, cborSize));
1125
1126         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1127         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1128
1129         EXPECT_EQ(NULL, parsedResource->next);
1130         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1131         EXPECT_EQ(NULL, parsedResource->types->next);
1132         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1133         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1134         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1135
1136         OICFree(cborData);
1137         OCPayloadDestroy(cparsed);
1138         OCDiscoveryPayloadDestroy(payload);
1139     }
1140     TEST(DiscoveryRTandIF, SingleItemBothTrim)
1141     {
1142         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1143         payload->sid = OICStrdup(sid1);
1144         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1145         payload->resources = resource;
1146
1147         OCResourcePayloadAddStringLL(&resource->types, "    rt.singleitem    ");
1148         OCResourcePayloadAddStringLL(&resource->interfaces, "    if.singleitem     ");
1149         resource->uri = OICStrdup("/uri/thing");
1150
1151         uint8_t* cborData;
1152         size_t cborSize;
1153         OCPayload* cparsed;
1154
1155         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1156         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1157                     cborData, cborSize));
1158
1159         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1160         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1161
1162         EXPECT_EQ(NULL, parsedResource->next);
1163         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1164         EXPECT_EQ(NULL, parsedResource->types->next);
1165         EXPECT_STREQ("rt.singleitem", parsedResource->types->value);
1166         EXPECT_EQ(NULL, parsedResource->interfaces->next);
1167         EXPECT_STREQ("if.singleitem", parsedResource->interfaces->value);
1168
1169         OICFree(cborData);
1170         OCPayloadDestroy(cparsed);
1171         OCDiscoveryPayloadDestroy(payload);
1172     }
1173     TEST(DiscoveryRTandIF, MultiItemsNormal)
1174     {
1175         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1176         payload->sid = OICStrdup(sid1);
1177         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1178         payload->resources = resource;
1179
1180         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem");
1181         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem");
1182         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem");
1183         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem");
1184         resource->uri = OICStrdup("/uri/thing");
1185
1186         uint8_t* cborData;
1187         size_t cborSize;
1188         OCPayload* cparsed;
1189
1190         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1191         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1192                     cborData, cborSize));
1193
1194         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1195         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1196
1197         EXPECT_EQ(NULL, parsedResource->next);
1198         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1199         EXPECT_EQ(NULL, parsedResource->types->next->next);
1200         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1201         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1202         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1203         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1204         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1205
1206         OICFree(cborData);
1207         OCPayloadDestroy(cparsed);
1208         OCDiscoveryPayloadDestroy(payload);
1209     }
1210     TEST(DiscoveryRTandIF, MultiItemExtraLeadSpaces)
1211     {
1212         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1213         payload->sid = OICStrdup(sid1);
1214         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1215         payload->resources = resource;
1216
1217         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem");
1218         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem");
1219         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem");
1220         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem");
1221         resource->uri = OICStrdup("/uri/thing");
1222
1223         uint8_t* cborData;
1224         size_t cborSize;
1225         OCPayload* cparsed;
1226
1227         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1228         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1229                     cborData, cborSize));
1230
1231         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1232         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1233
1234         EXPECT_EQ(NULL, parsedResource->next);
1235         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1236         EXPECT_EQ(NULL, parsedResource->types->next->next);
1237         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1238         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1239         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1240         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1241         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1242
1243         OICFree(cborData);
1244         OCPayloadDestroy(cparsed);
1245         OCDiscoveryPayloadDestroy(payload);
1246     }
1247     TEST(DiscoveryRTandIF, MultiItemExtraTrailSpaces)
1248     {
1249         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1250         payload->sid = OICStrdup(sid1);
1251         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1252         payload->resources = resource;
1253
1254         OCResourcePayloadAddStringLL(&resource->types, "rt.firstitem  ");
1255         OCResourcePayloadAddStringLL(&resource->types, "rt.seconditem  ");
1256         OCResourcePayloadAddStringLL(&resource->interfaces, "if.firstitem  ");
1257         OCResourcePayloadAddStringLL(&resource->interfaces, "if.seconditem  ");
1258         resource->uri = OICStrdup("/uri/thing");
1259
1260         uint8_t* cborData;
1261         size_t cborSize;
1262         OCPayload* cparsed;
1263
1264         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1265         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1266                     cborData, cborSize));
1267
1268         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1269         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1270
1271         EXPECT_EQ(NULL, parsedResource->next);
1272         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1273         EXPECT_EQ(NULL, parsedResource->types->next->next);
1274         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1275         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1276         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1277         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1278         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1279
1280         OICFree(cborData);
1281         OCPayloadDestroy(cparsed);
1282         OCDiscoveryPayloadDestroy(payload);
1283     }
1284     TEST(DiscoveryRTandIF, MultiItemBothSpaces)
1285     {
1286         OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
1287         payload->sid = OICStrdup(sid1);
1288         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1289         payload->resources = resource;
1290
1291         OCResourcePayloadAddStringLL(&resource->types, "  rt.firstitem  ");
1292         OCResourcePayloadAddStringLL(&resource->types, "  rt.seconditem  ");
1293         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.firstitem  ");
1294         OCResourcePayloadAddStringLL(&resource->interfaces, "  if.seconditem  ");
1295         resource->uri = OICStrdup("/uri/thing");
1296
1297         uint8_t* cborData;
1298         size_t cborSize;
1299         OCPayload* cparsed;
1300
1301         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1302         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_DISCOVERY,
1303                     cborData, cborSize));
1304
1305         EXPECT_EQ(1u, OCDiscoveryPayloadGetResourceCount((OCDiscoveryPayload*)cparsed));
1306         OCResourcePayload* parsedResource = ((OCDiscoveryPayload*)cparsed)->resources;
1307
1308         EXPECT_EQ(NULL, parsedResource->next);
1309         EXPECT_STREQ(sid1, ((OCDiscoveryPayload*)cparsed)->sid);
1310         EXPECT_EQ(NULL, parsedResource->types->next->next);
1311         EXPECT_STREQ("rt.firstitem", parsedResource->types->value);
1312         EXPECT_STREQ("rt.seconditem", parsedResource->types->next->value);
1313         EXPECT_EQ(NULL, parsedResource->interfaces->next->next);
1314         EXPECT_STREQ("if.firstitem", parsedResource->interfaces->value);
1315         EXPECT_STREQ("if.seconditem", parsedResource->interfaces->next->value);
1316
1317         OICFree(cborData);
1318         OCPayloadDestroy(cparsed);
1319         OCDiscoveryPayloadDestroy(payload);
1320     }
1321     TEST(RepresentationEncodingRTandIF, SingleItemNormal)
1322     {
1323         OCRepPayload* payload = OCRepPayloadCreate();
1324         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1325         OCRepPayloadAddInterface(payload, "if.firstitem");
1326
1327         uint8_t* cborData;
1328         size_t cborSize;
1329         OCPayload* cparsed;
1330
1331         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1332         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1333                     cborData, cborSize));
1334
1335         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1336
1337         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1338         EXPECT_EQ(NULL, parsedPayload->types->next);
1339         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1340         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1341
1342         OICFree(cborData);
1343         OCRepPayloadDestroy(payload);
1344         OCPayloadDestroy(cparsed);
1345     }
1346     TEST(RepresentationEncodingRTandIF, SingleItemFrontTrim)
1347     {
1348         OCRepPayload* payload = OCRepPayloadCreate();
1349         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1350         OCRepPayloadAddInterface(payload, "  if.firstitem");
1351
1352         uint8_t* cborData;
1353         size_t cborSize;
1354         OCPayload* cparsed;
1355
1356         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1357         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1358                     cborData, cborSize));
1359
1360         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1361
1362         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1363         EXPECT_EQ(NULL, parsedPayload->types->next);
1364         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1365         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1366
1367
1368         OICFree(cborData);
1369         OCRepPayloadDestroy(payload);
1370         OCPayloadDestroy(cparsed);
1371     }
1372     TEST(RepresentationEncodingRTandIF, SingleItemBackTrim)
1373     {
1374         OCRepPayload* payload = OCRepPayloadCreate();
1375         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1376         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1377
1378         uint8_t* cborData;
1379         size_t cborSize;
1380         OCPayload* cparsed;
1381
1382         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1383         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1384                     cborData, cborSize));
1385
1386         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1387
1388         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1389         EXPECT_EQ(NULL, parsedPayload->types->next);
1390         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1391         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1392
1393
1394         OICFree(cborData);
1395         OCRepPayloadDestroy(payload);
1396         OCPayloadDestroy(cparsed);
1397     }
1398     TEST(RepresentationEncodingRTandIF, SingleItemBothTrim)
1399     {
1400         OCRepPayload* payload = OCRepPayloadCreate();
1401         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1402         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1403
1404         uint8_t* cborData;
1405         size_t cborSize;
1406         OCPayload* cparsed;
1407
1408         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1409         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1410                     cborData, cborSize));
1411
1412         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1413
1414         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1415         EXPECT_EQ(NULL, parsedPayload->types->next);
1416         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1417         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1418
1419
1420         OICFree(cborData);
1421         OCRepPayloadDestroy(payload);
1422         OCPayloadDestroy(cparsed);
1423     }
1424     TEST(RepresentationEncodingRTandIF, MultiItemsNormal)
1425     {
1426         OCRepPayload* payload = OCRepPayloadCreate();
1427         OCRepPayloadAddResourceType(payload, "rt.firstitem");
1428         OCRepPayloadAddResourceType(payload, "rt.seconditem");
1429         OCRepPayloadAddInterface(payload, "if.firstitem");
1430         OCRepPayloadAddInterface(payload, "if.seconditem");
1431
1432         uint8_t* cborData;
1433         size_t cborSize;
1434         OCPayload* cparsed;
1435
1436         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1437         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1438                     cborData, cborSize));
1439
1440         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1441
1442         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1443         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1444         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1445         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1446         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1447         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1448
1449
1450         OICFree(cborData);
1451         OCRepPayloadDestroy(payload);
1452         OCPayloadDestroy(cparsed);
1453     }
1454     TEST(RepresentationEncodingRTandIF, MultiItemExtraLeadSpaces)
1455     {
1456         OCRepPayload* payload = OCRepPayloadCreate();
1457         OCRepPayloadAddResourceType(payload, "  rt.firstitem");
1458         OCRepPayloadAddResourceType(payload, "  rt.seconditem");
1459         OCRepPayloadAddInterface(payload, "  if.firstitem");
1460         OCRepPayloadAddInterface(payload, "  if.seconditem");
1461
1462         uint8_t* cborData;
1463         size_t cborSize;
1464         OCPayload* cparsed;
1465
1466         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1467         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1468                     cborData, cborSize));
1469
1470         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1471
1472         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1473         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1474         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1475         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1476         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1477         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1478
1479
1480         OICFree(cborData);
1481         OCRepPayloadDestroy(payload);
1482         OCPayloadDestroy(cparsed);
1483     }
1484     TEST(RepresentationEncodingRTandIF, MultiItemExtraTrailSpaces)
1485     {
1486         OCRepPayload* payload = OCRepPayloadCreate();
1487         OCRepPayloadAddResourceType(payload, "rt.firstitem  ");
1488         OCRepPayloadAddResourceType(payload, "rt.seconditem  ");
1489         OCRepPayloadAddInterface(payload, "if.firstitem  ");
1490         OCRepPayloadAddInterface(payload, "if.seconditem  ");
1491
1492         uint8_t* cborData;
1493         size_t cborSize;
1494         OCPayload* cparsed;
1495
1496         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1497         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1498                     cborData, cborSize));
1499
1500         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1501
1502         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1503         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1504         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1505         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1506         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1507         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1508
1509
1510         OICFree(cborData);
1511         OCRepPayloadDestroy(payload);
1512         OCPayloadDestroy(cparsed);
1513     }
1514     TEST(RepresentationEncodingRTandIF, MultiItemExtraMiddleSpaces)
1515     {
1516         OCRepPayload* payload = OCRepPayloadCreate();
1517         OCRepPayloadAddResourceType(payload, "  rt.firstitem  ");
1518         OCRepPayloadAddResourceType(payload, "  rt.seconditem  ");
1519         OCRepPayloadAddInterface(payload, "  if.firstitem  ");
1520         OCRepPayloadAddInterface(payload, "  if.seconditem  ");
1521
1522         uint8_t* cborData;
1523         size_t cborSize;
1524         OCPayload* cparsed;
1525
1526         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)payload, &cborData, &cborSize));
1527         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1528                     cborData, cborSize));
1529
1530         OCRepPayload* parsedPayload = (OCRepPayload*)cparsed;
1531
1532         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1533         EXPECT_STREQ("rt.seconditem", parsedPayload->types->next->value);
1534         EXPECT_EQ(NULL, parsedPayload->types->next->next);
1535         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1536         EXPECT_STREQ("if.seconditem", parsedPayload->interfaces->next->value);
1537         EXPECT_EQ(NULL, parsedPayload->interfaces->next->next);
1538
1539
1540         OICFree(cborData);
1541         OCRepPayloadDestroy(payload);
1542         OCPayloadDestroy(cparsed);
1543     }
1544     TEST(RepresentationEncodingRTandIF, TestPayloadContents)
1545     {
1546         OC::OCRepresentation subRep1;
1547         std::vector<std::string> types;
1548         types.push_back("rt.firstitem");
1549         std::vector<std::string> interfaces;
1550         interfaces.push_back("if.firstitem");
1551         subRep1.setResourceTypes(types);
1552         subRep1.setResourceInterfaces(interfaces);
1553         subRep1.setNULL("NullAttr");
1554         subRep1.setValue("IntAttr", 77);
1555         subRep1.setValue("DoubleAttr", 3.333);
1556         subRep1.setValue("BoolAttr", true);
1557         subRep1.setValue("StringAttr", std::string("String attr"));
1558
1559         OC::MessageContainer mc1;
1560         mc1.addRepresentation(subRep1);
1561
1562         OCRepPayload *repPayload = mc1.getPayload();
1563         EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, repPayload->base.type);
1564
1565         uint8_t *cborData = NULL;
1566         size_t cborSize = 0;
1567         OCPayload *cparsed = NULL;
1568
1569         EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)repPayload, &cborData, &cborSize));
1570         EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
1571                     cborData, cborSize));
1572
1573         OCRepPayload *parsedPayload = (OCRepPayload *)cparsed;
1574         EXPECT_EQ(NULL, parsedPayload->uri);
1575         EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
1576         EXPECT_EQ(NULL, parsedPayload->types->next);
1577         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
1578         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
1579
1580         // To make sure rt and if are not duplicated.
1581         EXPECT_STREQ("BoolAttr", parsedPayload->values->name);
1582         EXPECT_EQ(true, parsedPayload->values->b);
1583         EXPECT_EQ(OCREP_PROP_BOOL, parsedPayload->values->type);
1584         parsedPayload->values = parsedPayload->values->next;
1585
1586         EXPECT_STREQ("DoubleAttr", parsedPayload->values->name);
1587         EXPECT_EQ(OCREP_PROP_DOUBLE, parsedPayload->values->type);
1588         EXPECT_EQ(3.3330000000000002, parsedPayload->values->d);
1589         parsedPayload->values = parsedPayload->values->next;
1590
1591         EXPECT_STREQ("IntAttr", parsedPayload->values->name);
1592         EXPECT_EQ(77, parsedPayload->values->i);
1593         EXPECT_EQ(OCREP_PROP_INT, parsedPayload->values->type);
1594         parsedPayload->values = parsedPayload->values->next;
1595
1596         EXPECT_STREQ("NullAttr", parsedPayload->values->name);
1597         EXPECT_EQ(OCREP_PROP_NULL, parsedPayload->values->type);
1598         parsedPayload->values = parsedPayload->values->next;
1599
1600         EXPECT_STREQ("StringAttr", parsedPayload->values->name);
1601         EXPECT_STREQ("String attr", parsedPayload->values->str);
1602         EXPECT_EQ(OCREP_PROP_STRING, parsedPayload->values->type);
1603         parsedPayload->values = parsedPayload->values->next;
1604
1605         EXPECT_EQ(NULL, parsedPayload->values);
1606
1607         OICFree(cborData);
1608         OCRepPayloadDestroy(repPayload);
1609         OCPayloadDestroy(cparsed);
1610     }
1611 }