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