bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value);
bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value);
+/**
+ * This function allocates memory for the byte string and sets it in the payload.
+ *
+ * @param payload Pointer to the payload to which byte string needs to be added.
+ * @param name Name of the byte string.
+ * @param value Byte string and it's length.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value);
+
+/**
+ * This function sets the byte string in the payload.
+ *
+ * @param payload Pointer to the payload to which byte string needs to be added.
+ * @param name Name of the byte string.
+ * @param value Byte string and it's length.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name,
+ OCByteString* value);
+
+/**
+ * This function gets the byte string from the payload.
+ *
+ * @param payload Pointer to the payload from which byte string needs to be retrieved.
+ * @param name Name of the byte string.
+ * @param value Byte string and it's length.
+ *
+ * @note: Caller needs to invoke OCFree on value.bytes after it is finished using the byte string.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name,
+ OCByteString* value);
+
bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value);
bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value);
bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value);
OCRepPayload* value);
bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value);
+/**
+ * This function allocates memory for the byte string array and sets it in the payload.
+ *
+ * @param payload Pointer to the payload to which byte string array needs to be added.
+ * @param name Name of the byte string.
+ * @param array Byte string array.
+ * @param dimensions Number of byte strings in above array.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
+ OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+/**
+ * This function sets the byte string array in the payload.
+ *
+ * @param payload Pointer to the payload to which byte string array needs to be added.
+ * @param name Name of the byte string.
+ * @param array Byte string array.
+ * @param dimensions Number of byte strings in above array.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
+ const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+/**
+ * This function gets the byte string array from the payload.
+ *
+ * @param payload Pointer to the payload from which byte string array needs to be retrieved.
+ * @param name Name of the byte string array.
+ * @param value Byte string array.
+ * @param dimensions Number of byte strings in above array.
+ *
+ * @note: Caller needs to invoke OICFree on 'bytes' field of all array elements after it is
+ * finished using the byte string array.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
+ OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
OCREP_PROP_DOUBLE,
OCREP_PROP_BOOL,
OCREP_PROP_STRING,
+ OCREP_PROP_BYTE_STRING,
OCREP_PROP_OBJECT,
OCREP_PROP_ARRAY
}OCRepPayloadPropType;
+/** This structure will be used to represent a binary string for CBOR payloads.*/
+typedef struct
+{
+ /** pointer to data bytes.*/
+ uint8_t* bytes;
+
+ /** number of data bytes.*/
+ size_t len;
+} OCByteString;
+
#define MAX_REP_ARRAY_DEPTH 3
typedef struct
{
double* dArray;
bool* bArray;
char** strArray;
+
+ /** pointer to ByteString array.*/
+ OCByteString* ocByteStrArray;
+
struct OCRepPayload** objArray;
};
} OCRepPayloadValueArray;
double d;
bool b;
char* str;
+
+ /** ByteString object.*/
+ OCByteString ocByteStr;
+
struct OCRepPayload* obj;
OCRepPayloadValueArray arr;
};
case OCREP_PROP_STRING:
OC_LOG_V(level, PL_TAG, "\t\t%s(string):%s", val->name, val->str);
break;
+ case OCREP_PROP_BYTE_STRING:
+ OC_LOG_V(level, PL_TAG, "\t\t%s(binary):", val->name);
+ OC_LOG_BUFFER(level, PL_TAG, val->ocByteStr.bytes, val->ocByteStr.len);
+ break;
case OCREP_PROP_OBJECT:
// Note: Only prints the URI (if available), to print further, you'll
// need to dig into the object better!
val->arr.dimensions[0], val->arr.dimensions[1],
val->arr.dimensions[2]);
break;
+ case OCREP_PROP_BYTE_STRING:
+ OC_LOG_V(level, PL_TAG, "\t\t%s(byte array):%lld x %lld x %lld",
+ val->name,
+ val->arr.dimensions[0], val->arr.dimensions[1],
+ val->arr.dimensions[2]);
+ break;
case OCREP_PROP_OBJECT:
OC_LOG_V(level, PL_TAG, "\t\t%s(OCRep array):%zu x %zu x %zu",
val->name,
{
OICFree(val->str);
}
+ else if(val->type == OCREP_PROP_BYTE_STRING)
+ {
+ OICFree(val->ocByteStr.bytes);
+ }
else if (val->type == OCREP_PROP_OBJECT)
{
OCRepPayloadDestroy(val->obj);
}
OICFree(val->arr.strArray);
break;
+ case OCREP_PROP_BYTE_STRING:
+ for (size_t i = 0; i< dimTotal; ++i)
+ {
+ OICFree(val->arr.ocByteStrArray[i].bytes);
+ }
+ OICFree(val->arr.ocByteStrArray);
+ break;
case OCREP_PROP_OBJECT:
for(size_t i = 0; i< dimTotal;++i)
{
case OCREP_PROP_STRING:
val->str = (char*)value;
return val->str != NULL;
+ case OCREP_PROP_BYTE_STRING:
+ val->ocByteStr = *(OCByteString*)value;
+ break;
case OCREP_PROP_NULL:
return val != NULL;
case OCREP_PROP_ARRAY:
return *value != NULL;
}
+bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
+{
+ if (!value.bytes || !value.len)
+ {
+ return false;
+ }
+
+ OCByteString ocByteStr = {
+ .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
+ .len = value.len };
+
+ if(!ocByteStr.bytes)
+ {
+ return false;
+ }
+ memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
+
+ bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
+
+ if(!b)
+ {
+ OICFree(ocByteStr.bytes);
+ }
+ return b;
+}
+
+bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
+{
+ return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
+}
+
+bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
+{
+ OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+ if (!val || val->type != OCREP_PROP_BYTE_STRING)
+ {
+ return false;
+ }
+
+ if (!value)
+ {
+ return false;
+ }
+
+ value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
+ if (!value->bytes)
+ {
+ return false;
+ }
+ value->len = val->ocByteStr.len;
+ memcpy(value->bytes, val->ocByteStr.bytes, value->len);
+
+ return true;
+}
+
bool OCRepPayloadSetPropBool(OCRepPayload* payload,
const char* name, bool value)
{
return total;
}
+
+bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
+ OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+ OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+ if (!val)
+ {
+ return false;
+ }
+
+ val->arr.type = OCREP_PROP_BYTE_STRING;
+ memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+ val->arr.ocByteStrArray = array;
+
+ return true;
+}
+
+bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
+ const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+ if (!array)
+ {
+ return NULL;
+ }
+
+ size_t dimTotal = calcDimTotal(dimensions);
+ if (dimTotal == 0)
+ {
+ return false;
+ }
+
+ OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
+
+ if (!newArray)
+ {
+ return false;
+ }
+
+ for (size_t i = 0; i < dimTotal; ++i)
+ {
+ newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
+ if (NULL == newArray[i].bytes)
+ {
+ for (size_t j = 0; j < i; ++j)
+ {
+ OICFree(newArray[j].bytes);
+ }
+
+ OICFree(newArray);
+ return false;
+ }
+ newArray[i].len = array[i].len;
+ memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
+ }
+
+ bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
+ if (!b)
+ {
+ for (size_t i = 0; i < dimTotal; ++i)
+ {
+ OICFree(newArray[i].bytes);
+ }
+
+ OICFree(newArray);
+ }
+ return b;
+}
+
+bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
+ OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+ OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+ if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
+ || !val->arr.ocByteStrArray)
+ {
+ return false;
+ }
+
+ size_t dimTotal = calcDimTotal(val->arr.dimensions);
+ if (dimTotal == 0)
+ {
+ return false;
+ }
+
+ *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
+ if (!*array)
+ {
+ return false;
+ }
+
+ for (size_t i = 0; i < dimTotal; ++i)
+ {
+ OCByteString* tmp = &(*array)[i];
+ tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
+ if (NULL == tmp->bytes)
+ {
+ for (size_t j = 0; j < i; ++j)
+ {
+ OCByteString* tmp = &(*array)[j];
+ OICFree(tmp->bytes);
+ }
+ OICFree(*array);
+ *array = NULL;
+
+ return false;
+ }
+ tmp->len = val->arr.ocByteStrArray[i].len;
+ memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
+ }
+
+ memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+ return true;
+}
+
+
bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
{
strlen(valArray->strArray[index]));
}
break;
+ case OCREP_PROP_BYTE_STRING:
+ if (!valArray->strArray[index])
+ {
+ err = err | cbor_encode_null(array);
+ }
+ else
+ {
+ err = err | cbor_encode_byte_string(array, valArray->ocByteStrArray[index].bytes,
+ valArray->ocByteStrArray[index].len);
+ }
+ break;
case OCREP_PROP_OBJECT:
if (!valArray->objArray[index])
{
err = err | cbor_encode_text_string(&repMap,
value->str, strlen(value->str));
break;
+ case OCREP_PROP_BYTE_STRING:
+ err = err | cbor_encode_byte_string(&repMap,
+ value->ocByteStr.bytes, value->ocByteStr.len);
+ break;
case OCREP_PROP_OBJECT:
err = err | OCConvertSingleRepPayload(&repMap, value->obj);
break;
return OCREP_PROP_BOOL;
case CborTextStringType:
return OCREP_PROP_STRING;
+ case CborByteStringType:
+ return OCREP_PROP_BYTE_STRING;
case CborMapType:
return OCREP_PROP_OBJECT;
case CborArrayType:
return sizeof (bool);
case OCREP_PROP_STRING:
return sizeof (char*);
+ case OCREP_PROP_BYTE_STRING:
+ return sizeof (OCByteString);
case OCREP_PROP_OBJECT:
return sizeof (OCRepPayload*);
default:
size_t i = 0;
char* tempStr = NULL;
+ OCByteString ocByteStr = { .bytes = NULL, .len = 0};
size_t tempLen = 0;
OCRepPayload* tempPl = NULL;
);
}
break;
+ case OCREP_PROP_BYTE_STRING:
+ if (dimensions[1] == 0)
+ {
+ err = err || cbor_value_dup_byte_string(&insideArray,
+ &(ocByteStr.bytes), &(ocByteStr.len), NULL);
+ ((OCByteString*)targetArray)[i] = ocByteStr;
+ }
+ else
+ {
+ err = err || OCParseArrayFillArray(&insideArray, newdim,
+ type,
+ &(((OCByteString*)targetArray)[arrayStep(dimensions, i)])
+ );
+ }
+ break;
case OCREP_PROP_OBJECT:
if (dimensions[1] == 0)
{
err = true;
}
break;
+ case OCREP_PROP_BYTE_STRING:
+ if (err || !OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString*)arr, dimensions))
+ {
+ for (size_t i = 0; i < dimTotal; ++i)
+ {
+ OICFree(((OCByteString*)arr)[i].bytes);
+ }
+ OICFree(arr);
+ err = true;
+ }
+ break;
case OCREP_PROP_OBJECT:
if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
{
int64_t intval = 0;
bool boolval = false;
char* strval = NULL;
+ uint8_t* bytestrval = NULL;
double doubleval = 0;
OCRepPayload* pl;
err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
}
break;
+ case CborByteStringType:
+ err = err || cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
+ if (!err)
+ {
+ OCByteString tmp = {.bytes = bytestrval, .len = len};
+ err = !OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
+ }
+ break;
case CborMapType:
err = err || OCParseSingleRepPayload(&pl, &repMap);
if (!err)
# Source files and Targets
######################################################################
stacktests = stacktest_env.Program('stacktests', ['stacktests.cpp'])
+cbortests = stacktest_env.Program('cbortests', ['cbortests.cpp'])
-Alias("test", [stacktests])
+Alias("test", [stacktests, cbortests])
env.AppendTarget('test')
if env.get('TEST') == '1':
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+extern "C"
+{
+ #include "ocstack.h"
+ #include "ocpayload.h"
+ #include "ocpayloadcbor.h"
+ #include "logger.h"
+ #include "oic_malloc.h"
+}
+
+#include "gtest/gtest.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <stdint.h>
+
+#include "gtest_helper.h"
+
+class CborByteStringTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Create Payload
+ payload_in = OCRepPayloadCreate();
+ ASSERT_TRUE(payload_in != NULL);
+ }
+
+ virtual void TearDown() {
+ OCPayloadDestroy((OCPayload*)payload_in);
+ }
+
+ OCRepPayload* payload_in;
+};
+
+TEST_F(CborByteStringTest, ByteStringSetGetTest)
+{
+ OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+ OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+ uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
+ 0xD, 0xE, 0xF};
+ OCByteString quakedata_in = { binval, sizeof(binval)};
+
+ EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));
+
+ OCByteString quakedata_out = { NULL, 0};
+ ASSERT_EQ(true, OCRepPayloadGetPropByteString(payload_in, "quakedata", &quakedata_out));
+
+ EXPECT_EQ(quakedata_in.len, quakedata_out.len);
+ EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));
+
+ // Cleanup
+ OICFree(quakedata_out.bytes);
+}
+
+TEST_F(CborByteStringTest, ByteStringConvertParseTest)
+{
+ OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+ OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+ uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
+ 0xD, 0xE, 0xF};
+ OCByteString quakedata_in = { binval, sizeof(binval)};
+
+ // Set ByteString in Payload
+ EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));
+
+ // Convert OCPayload to CBOR
+ uint8_t *payload_cbor = NULL;
+ size_t payload_cbor_size = 0;
+ EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, &payload_cbor, &payload_cbor_size));
+
+#ifdef CBOR_BIN_STRING_DEBUG
+ FILE *fp = fopen("binstring.cbor", "wb+");
+ if (fp)
+ {
+ fwrite(payload_cbor, 1, payload_cbor_size, fp);
+ fclose(fp);
+ }
+#endif //CBOR_BIN_STRING_DEBUG
+
+ // Parse CBOR back to OCPayload
+ OCPayload* payload_out = NULL;
+ EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, PAYLOAD_TYPE_REPRESENTATION,
+ payload_cbor, payload_cbor_size));
+
+ OCByteString quakedata_out = {NULL, 0};
+ ASSERT_EQ(true, OCRepPayloadGetPropByteString((OCRepPayload*)payload_out, "quakedata", &quakedata_out));
+
+ // Compare input and output data
+ EXPECT_EQ(quakedata_in.len, quakedata_out.len);
+ EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));
+
+ // Cleanup
+ OICFree(payload_cbor);
+ OICFree(quakedata_out.bytes);
+ OCPayloadDestroy((OCPayload*)payload_out);
+}
+
+TEST_F(CborByteStringTest, ByteStringArraySetGetTest )
+{
+ OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+ OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+ size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
+ uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
+ uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
+ uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
+
+ OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
+ {binval2, sizeof(binval2)},
+ {binval3, sizeof(binval3)}};
+
+ EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
+ quakedata_in, dimensions_in));
+
+ OCByteString* quakedata_out = NULL;
+ size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
+ ASSERT_EQ(true, OCRepPayloadGetByteStringArray(payload_in, "quakedata",
+ &quakedata_out, dimensions_out));
+
+ for(size_t i = 0; i < dimensions_in[0]; i++)
+ {
+ EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
+ EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
+ }
+
+ // Cleanup
+ for(size_t i = 0; i < dimensions_out[0]; i++)
+ {
+ OICFree(quakedata_out[i].bytes);
+ }
+ OICFree(quakedata_out);
+}
+
+
+TEST_F(CborByteStringTest, ByteStringArrayConvertParseTest )
+{
+ OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+ OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+ size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
+ uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
+ uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
+ uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
+
+ OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
+ {binval2, sizeof(binval2)},
+ {binval3, sizeof(binval3)}};
+
+ EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
+ quakedata_in, dimensions_in));
+
+ // Convert OCPayload to CBOR
+ uint8_t *payload_cbor = NULL;
+ size_t payload_cbor_size = 0;
+ EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, &payload_cbor, &payload_cbor_size));
+#ifdef CBOR_BIN_STRING_DEBUG
+ FILE *fp = fopen("binstringarr.cbor", "wb+");
+ if (fp)
+ {
+ fwrite(payload_cbor, 1, payload_cbor_size, fp);
+ fclose(fp);
+ }
+#endif //CBOR_BIN_STRING_DEBUG
+
+ // Parse CBOR back to OCPayload
+ OCPayload* payload_out = NULL;
+ EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, PAYLOAD_TYPE_REPRESENTATION,
+ payload_cbor, payload_cbor_size));
+
+ OCByteString* quakedata_out = NULL;
+ size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
+ ASSERT_EQ(true, OCRepPayloadGetByteStringArray((OCRepPayload*)payload_out, "quakedata",
+ &quakedata_out, dimensions_out));
+
+ for(size_t i = 0; i < dimensions_in[0]; i++)
+ {
+ EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
+ EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
+ }
+
+ // Cleanup
+ OICFree(payload_cbor);
+ for(size_t i = 0; i < dimensions_out[0]; i++)
+ {
+ OICFree(quakedata_out[i].bytes);
+ }
+ OICFree(quakedata_out);
+
+ OCPayloadDestroy((OCPayload*)payload_out);
+}