int64_t err = 0;
cbor_encoder_init(&encoder, outPayload, *size, 0);
- CborEncoder rootMap;
- err = err | cbor_encoder_create_map(&encoder, &rootMap, CborIndefiniteLength);
+ CborEncoder rootMap ;
- if (payload->types)
+ size_t arrayCount = 0;
+ for (OCRepPayload *temp = payload; temp; temp = temp->next)
{
- OC_LOG(INFO, TAG, "Payload has types or interfaces");
- char* joinedTypes = OCStringLLJoin(payload->types);
- if (joinedTypes)
- {
- err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_RESOURCE_TYPE,
- sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
- err = err | cbor_encode_text_string(&rootMap, joinedTypes,
- strlen(joinedTypes));
- OICFree(joinedTypes);
- }
- else
- {
- return OC_STACK_NO_MEMORY;
- }
+ arrayCount++;
+ }
+ CborEncoder rootArray;
+ if (arrayCount > 1)
+ {
+ err = err | cbor_encoder_create_array(&encoder, &rootArray, arrayCount);
}
- if (payload->interfaces)
+
+ while (payload != NULL && (err == CborNoError))
{
- char* joinedInterfaces = OCStringLLJoin(payload->interfaces);
- if (joinedInterfaces)
+ err = err | cbor_encoder_create_map(((arrayCount == 1)? &encoder: &rootArray),
+ &rootMap, CborIndefiniteLength);
+ // Only in case of collection href is included.
+ if (arrayCount > 1 && payload->uri && strlen(payload->uri) > 0)
{
- err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_INTERFACE,
- sizeof(OC_RSRVD_INTERFACE) - 1);
- err = err | cbor_encode_text_string(&rootMap, joinedInterfaces,
- strlen(joinedInterfaces));
- OICFree(joinedInterfaces);
+ OC_LOG(INFO, TAG, "Payload has uri");
+ err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_HREF,
+ strlen(OC_RSRVD_HREF));
+ err = err | cbor_encode_text_string(&rootMap, payload->uri,
+ strlen(payload->uri));
}
- else
+ if (payload->types)
{
- return OC_STACK_NO_MEMORY;
+ OC_LOG(INFO, TAG, "Payload has types");
+ char* joinedTypes = OCStringLLJoin(payload->types);
+ if (joinedTypes)
+ {
+ err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_RESOURCE_TYPE,
+ strlen(OC_RSRVD_RESOURCE_TYPE));
+ err = err | cbor_encode_text_string(&rootMap, joinedTypes,
+ strlen(joinedTypes));
+ OICFree(joinedTypes);
+ }
+ else
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ }
+ if (payload->interfaces)
+ {
+ OC_LOG(INFO, TAG, "Payload has interfaces");
+ char* joinedInterfaces = OCStringLLJoin(payload->interfaces);
+ if (joinedInterfaces)
+ {
+ err = err | cbor_encode_text_string(&rootMap, OC_RSRVD_INTERFACE,
+ strlen(OC_RSRVD_INTERFACE));
+ err = err | cbor_encode_text_string(&rootMap, joinedInterfaces,
+ strlen(joinedInterfaces));
+ OICFree(joinedInterfaces);
+ }
+ else
+ {
+ return OC_STACK_NO_MEMORY;
+ }
}
- }
- while(payload != NULL && (err == 0 || err == CborErrorOutOfMemory))
- {
err = err | OCConvertSingleRepPayload(&rootMap, payload);
+ err = err | cbor_encoder_close_container(((arrayCount == 1) ? &encoder: &rootArray),
+ &rootMap);
payload = payload->next;
}
-
- // Close main array
- err = err | cbor_encoder_close_container(&encoder, &rootMap);
+ if (arrayCount > 1)
+ {
+ err = err | cbor_encoder_close_container(&encoder, &rootArray);
+ }
return checkError(err, &encoder, outPayload, size);
}
}
OCRepPayload* curPayload = *outPayload;
-
- size_t len;
- CborValue repMap;
+ size_t len = 0;
+ CborValue repMap = *objMap;
err = err || cbor_value_enter_container(objMap, &repMap);
-
- while(!err && cbor_value_is_valid(&repMap))
+ while (!err && cbor_value_is_valid(&repMap))
{
- char* name;
- err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
- err = err || cbor_value_advance(&repMap);
+ char *name = NULL;
+ if (cbor_value_is_text_string(&repMap))
+ {
+ err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
+ err = err || cbor_value_advance(&repMap);
+ if (name &&
+ ((0 == strcmp(OC_RSRVD_HREF, name)) ||
+ (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
+ (0 == strcmp(OC_RSRVD_INTERFACE, name))))
+ {
+ err = err || cbor_value_advance(&repMap);
+ OICFree(name);
+ continue;
+ }
+ }
CborType type = cbor_value_get_type(&repMap);
+
switch(type)
{
case CborNullType:
}
OICFree(name);
}
-
- err = err || cbor_value_leave_container(objMap, &repMap);
-
- if(err)
+ if (cbor_value_is_container(objMap))
+ {
+ err = err || cbor_value_leave_container(objMap, &repMap);
+ }
+ if (err)
{
OCRepPayloadDestroy(*outPayload);
*outPayload = NULL;
return err;
}
-static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* rootMap)
+static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* root)
{
if (!outPayload)
{
OCRepPayload *rootPayload = NULL;
OCRepPayload *curPayload = NULL;
- OCRepPayload *temp = OCRepPayloadCreate();
- if (!temp)
- {
- return OC_STACK_NO_MEMORY;
- }
CborValue curVal;
bool err = false;
- size_t len;
- err = err || cbor_value_map_find_value(rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
- if(cbor_value_is_text_string(&curVal))
+ size_t len = 0;
+ CborValue rootMap = *root;
+ if (cbor_value_is_array(root))
+ {
+ cbor_value_enter_container(root, &rootMap);
+ }
+ while (!err && cbor_value_is_valid(&rootMap))
{
- char* allRt = NULL;
- err = err || cbor_value_dup_text_string(&curVal, &allRt, &len, NULL);
- if (allRt)
+ OCRepPayload *temp = OCRepPayloadCreate();
+ if (!temp)
{
- char* savePtr;
- char* curPtr = strtok_r(allRt, " ", &savePtr);
- while (curPtr)
+ return OC_STACK_NO_MEMORY;
+ }
+ if (!err && cbor_value_is_map(&rootMap))
+ {
+ err = err || cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
+ if (cbor_value_is_valid(&curVal))
{
- char* trimmed = InPlaceStringTrim(curPtr);
- if (trimmed[0] != '\0')
+ err = err || cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
+ }
+ }
+ if (!err && cbor_value_is_map(&rootMap))
+ {
+ err = err || cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ if(cbor_value_is_text_string(&curVal))
+ {
+ char* allRt = NULL;
+ err = err || cbor_value_dup_text_string(&curVal, &allRt, &len, NULL);
+ if (allRt)
{
- OCRepPayloadAddResourceType(temp, curPtr);
+ char* savePtr;
+ char* curPtr = strtok_r(allRt, " ", &savePtr);
+ while (curPtr)
+ {
+ char* trimmed = InPlaceStringTrim(curPtr);
+ if (trimmed[0] != '\0')
+ {
+ OCRepPayloadAddResourceType(temp, curPtr);
+ }
+ curPtr = strtok_r(NULL, " ", &savePtr);
+ }
}
- curPtr = strtok_r(NULL, " ", &savePtr);
+ OICFree(allRt);
}
}
- OICFree(allRt);
- }
-
- err = err || cbor_value_map_find_value(rootMap, OC_RSRVD_INTERFACE, &curVal);
- if(cbor_value_is_text_string(&curVal))
- {
- char* allIf = NULL;
- err = err || cbor_value_dup_text_string(&curVal, &allIf, &len, NULL);
- if (allIf)
+ if (!err && cbor_value_is_map(&rootMap))
{
- char* savePtr;
- char* curPtr = strtok_r(allIf, " ", &savePtr);
- while (curPtr)
+ err = err || cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
+ if(cbor_value_is_text_string(&curVal))
{
- char* trimmed = InPlaceStringTrim(curPtr);
- if (trimmed[0] != '\0')
+ char* allIf = NULL;
+ err = err || cbor_value_dup_text_string(&curVal, &allIf, &len, NULL);
+ if (allIf)
{
- OCRepPayloadAddInterface(temp, curPtr);
+ char* savePtr;
+ char* curPtr = strtok_r(allIf, " ", &savePtr);
+ while (curPtr)
+ {
+ char* trimmed = InPlaceStringTrim(curPtr);
+ if (trimmed[0] != '\0')
+ {
+ OCRepPayloadAddInterface(temp, curPtr);
+ }
+ curPtr = strtok_r(NULL, " ", &savePtr);
+ }
}
- curPtr = strtok_r(NULL, " ", &savePtr);
+ OICFree(allIf);
}
}
- OICFree(allIf);
- }
-
- while (!err && cbor_value_is_map(rootMap))
- {
- err = err || OCParseSingleRepPayload(&temp, rootMap);
-
- if(rootPayload == NULL)
+ if (!err && cbor_value_is_map(&rootMap))
+ {
+ err = err || OCParseSingleRepPayload(&temp, &rootMap);
+ }
+ if (rootPayload == NULL)
{
rootPayload = temp;
curPayload = temp;
curPayload->next = temp;
curPayload = curPayload->next;
}
-
- if (cbor_value_is_valid(rootMap))
- {
- err = err || cbor_value_advance(rootMap);
- }
-
- if(err)
+ if (err)
{
OCRepPayloadDestroy(rootPayload);
OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
return OC_STACK_MALFORMED_RESPONSE;
}
+ if (cbor_value_is_array(&rootMap))
+ {
+ err = err || cbor_value_advance(&rootMap);
+ }
}
-
- *outPayload = (OCPayload*)rootPayload;
+ *outPayload = (OCPayload *)rootPayload;
return OC_STACK_OK;
}
OCPayloadDestroy(cparsed);
}
+ TEST(RepresentationEncoding, RepAttributeEmpty)
+ {
+ OC::OCRepresentation startRep;
+ std::vector<int> iarr {};
+ startRep["iarr"] = {};
+
+ OC::MessageContainer mc1;
+ mc1.addRepresentation(startRep);
+
+ OCRepPayload* cstart = mc1.getPayload();
+ EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, cstart->base.type);
+
+ uint8_t *cborData = NULL;
+ size_t cborSize = 0;
+ OCPayload *cparsed = NULL;
+ EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)cstart, &cborData, &cborSize));
+ EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
+ cborData, cborSize));
+ OCPayloadDestroy((OCPayload*)cstart);
+ OICFree(cborData);
+
+ OC::MessageContainer mc2;
+ mc2.setPayload(cparsed);
+ EXPECT_EQ(1u, mc2.representations().size());
+ const OC::OCRepresentation& r = mc2.representations()[0];
+
+ std::vector<int> iarr2 = r["iarr"];
+
+ EXPECT_EQ(iarr, iarr2);
+ OCPayloadDestroy(cparsed);
+ }
+
TEST(RepresentationEncoding, RepAttribute)
{
OC::OCRepresentation startRep;
OCRepPayloadDestroy(payload);
OCPayloadDestroy(cparsed);
}
+ TEST(RepresentationEncodingRTandIF, TestPayloadContents)
+ {
+ OC::OCRepresentation subRep1;
+ std::vector<std::string> types;
+ types.push_back("rt.firstitem");
+ std::vector<std::string> interfaces;
+ interfaces.push_back("if.firstitem");
+ subRep1.setResourceTypes(types);
+ subRep1.setResourceInterfaces(interfaces);
+ subRep1.setNULL("NullAttr");
+ subRep1.setValue("IntAttr", 77);
+ subRep1.setValue("DoubleAttr", 3.333);
+ subRep1.setValue("BoolAttr", true);
+ subRep1.setValue("StringAttr", std::string("String attr"));
+
+ OC::MessageContainer mc1;
+ mc1.addRepresentation(subRep1);
+
+ OCRepPayload *repPayload = mc1.getPayload();
+ EXPECT_EQ(PAYLOAD_TYPE_REPRESENTATION, repPayload->base.type);
+
+ uint8_t *cborData = NULL;
+ size_t cborSize = 0;
+ OCPayload *cparsed = NULL;
+
+ EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*)repPayload, &cborData, &cborSize));
+ EXPECT_EQ(OC_STACK_OK, OCParsePayload(&cparsed, PAYLOAD_TYPE_REPRESENTATION,
+ cborData, cborSize));
+
+ OCRepPayload *parsedPayload = (OCRepPayload *)cparsed;
+ EXPECT_EQ(NULL, parsedPayload->uri);
+ EXPECT_STREQ("rt.firstitem", parsedPayload->types->value);
+ EXPECT_EQ(NULL, parsedPayload->types->next);
+ EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
+ EXPECT_EQ(NULL, parsedPayload->interfaces->next);
+
+ // To make sure rt and if are not duplicated.
+ EXPECT_STREQ("BoolAttr", parsedPayload->values->name);
+ EXPECT_EQ(true, parsedPayload->values->b);
+ EXPECT_EQ(OCREP_PROP_BOOL, parsedPayload->values->type);
+ parsedPayload->values = parsedPayload->values->next;
+
+ EXPECT_STREQ("DoubleAttr", parsedPayload->values->name);
+ EXPECT_EQ(OCREP_PROP_DOUBLE, parsedPayload->values->type);
+ EXPECT_EQ(3.3330000000000002, parsedPayload->values->d);
+ parsedPayload->values = parsedPayload->values->next;
+
+ EXPECT_STREQ("IntAttr", parsedPayload->values->name);
+ EXPECT_EQ(77, parsedPayload->values->i);
+ EXPECT_EQ(OCREP_PROP_INT, parsedPayload->values->type);
+ parsedPayload->values = parsedPayload->values->next;
+
+ EXPECT_STREQ("NullAttr", parsedPayload->values->name);
+ EXPECT_EQ(OCREP_PROP_NULL, parsedPayload->values->type);
+ parsedPayload->values = parsedPayload->values->next;
+
+ EXPECT_STREQ("StringAttr", parsedPayload->values->name);
+ EXPECT_STREQ("String attr", parsedPayload->values->str);
+ EXPECT_EQ(OCREP_PROP_STRING, parsedPayload->values->type);
+ parsedPayload->values = parsedPayload->values->next;
+
+ EXPECT_EQ(NULL, parsedPayload->values);
+
+ OICFree(cborData);
+ OCRepPayloadDestroy(repPayload);
+ OCPayloadDestroy(cparsed);
+ }
}