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