static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType* type) { bool err = false; CborValue insideArray; *type = OCREP_PROP_NULL; dimensions[0] = dimensions[1] = dimensions[2] = 0; err = err || cbor_value_enter_container(parent, &insideArray); while (cbor_value_is_valid(&insideArray)) { OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray)); if (tempType == OCREP_PROP_ARRAY) { size_t subdim[MAX_REP_ARRAY_DEPTH]; tempType = OCREP_PROP_NULL; err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType); if (subdim[2] != 0) { OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep"); } dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0]; dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1]; if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType) { OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)"); return true; } else if (*type == OCREP_PROP_NULL) { // We don't know the type of this array yet, so the assignment is OK *type = tempType; } } else if (*type == OCREP_PROP_NULL) { // We don't know the type of this array yet, so the assignment is OK *type = tempType; } // tempType is allowed to be NULL, since it might now know the answer yet else if (tempType != OCREP_PROP_NULL && *type != tempType) { // this is an invalid situation! OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed"); return true; } ++dimensions[0]; cbor_value_advance(&insideArray); } return err; }
static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue *objMap) { if (!outPayload) { return false; } bool err = false; if (cbor_value_is_map(objMap)) { if (!*outPayload) { *outPayload = OCRepPayloadCreate(); if(!*outPayload) { return CborErrorOutOfMemory; } } OCRepPayload* curPayload = *outPayload; size_t len; CborValue repMap; err = err || cbor_value_enter_container(objMap, &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); CborType type = cbor_value_get_type(&repMap); switch(type) { case CborNullType: err = !OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: { int64_t intval = 0; err = err || cbor_value_get_int64(&repMap, &intval); if (!err) { err = !OCRepPayloadSetPropInt(curPayload, name, intval); } } break; case CborDoubleType: { double doubleval = 0; err = err || cbor_value_get_double(&repMap, &doubleval); if (!err) { err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval); } } break; case CborBooleanType: { bool boolval = false; err = err || cbor_value_get_boolean(&repMap, &boolval); if (!err) { err = !OCRepPayloadSetPropBool(curPayload, name, boolval); } } break; case CborTextStringType: { char* strval = NULL; err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL); if (!err) { err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } } break; case CborByteStringType: { uint8_t* bytestrval = NULL; 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: { OCRepPayload *pl = NULL; err = err || OCParseSingleRepPayload(&pl, &repMap); if (!err) { err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } } break; case CborArrayType: err = err || OCParseArray(curPayload, name, &repMap); break; default: OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); err = true; } if (type != CborMapType && cbor_value_is_valid(&repMap)) { err = err || cbor_value_advance(&repMap); } OICFree(name); } err = err || cbor_value_leave_container(objMap, &repMap); if(err) { OCRepPayloadDestroy(*outPayload); *outPayload = NULL; } }
static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void* targetArray) { bool err = false; CborValue insideArray; err = err || cbor_value_enter_container(parent, &insideArray); size_t i = 0; char* tempStr = NULL; size_t tempLen = 0; OCRepPayload* tempPl = NULL; size_t newdim[MAX_REP_ARRAY_DEPTH]; newdim[0] = dimensions[1]; newdim[1] = dimensions[2]; newdim[2] = 0; while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray)) { bool noAdvance = false; if (cbor_value_get_type(&insideArray) != CborNullType) { switch (type) { case OCREP_PROP_INT: if (dimensions[1] == 0) { err = err || cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i])); } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((int64_t*)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_DOUBLE: if (dimensions[1] == 0) { err = err || cbor_value_get_double(&insideArray, &(((double*)targetArray)[i])); } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((double*)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_BOOL: if (dimensions[1] == 0) { err = err || cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i])); } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((bool*)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_STRING: if (dimensions[1] == 0) { err = err || cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL); ((char**)targetArray)[i] = tempStr; tempStr = NULL; } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((char**)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_OBJECT: if (dimensions[1] == 0) { err = err || OCParseSingleRepPayload(&tempPl, &insideArray); ((OCRepPayload**)targetArray)[i] = tempPl; tempPl = NULL; noAdvance = true; } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]) ); } break; default: OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); err = true; break; } } ++i; if (!noAdvance && cbor_value_is_valid(&insideArray)) { err = err || cbor_value_advance(&insideArray); } } return err; }
static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent) { if (!outPayload) { return false; } *outPayload = OCRepPayloadCreate(); OCRepPayload* curPayload = *outPayload; bool err = false; if(!*outPayload) { return CborErrorOutOfMemory; } size_t len; CborValue curVal; err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal); if(cbor_value_is_valid(&curVal)) { err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len, NULL); } err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal); if(cbor_value_is_valid(&curVal)) { CborValue insidePropValue = {0}; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &insidePropValue); if(cbor_value_is_text_string(&insidePropValue)) { char* allRt = NULL; err = err || cbor_value_dup_text_string(&insidePropValue, &allRt, &len, NULL); char* savePtr; if (allRt) { char* curPtr = strtok_r(allRt, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] != '\0') { OCRepPayloadAddResourceType(curPayload, curPtr); } curPtr = strtok_r(NULL, " ", &savePtr); } } OICFree(allRt); } err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropValue); if(cbor_value_is_text_string(&insidePropValue)) { char* allIf = NULL; err = err || cbor_value_dup_text_string(&insidePropValue, &allIf, &len, NULL); char* savePtr; if (allIf) { char* curPtr = strtok_r(allIf, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] != '\0') { OCRepPayloadAddInterface(curPayload, curPtr); } curPtr = strtok_r(NULL, " ", &savePtr); } } OICFree(allIf); } } err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal); if(cbor_value_is_map(&curVal)) { CborValue repMap; err = err || cbor_value_enter_container(&curVal, &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); int64_t intval = 0; bool boolval = false; char* strval = NULL; double doubleval = 0; OCRepPayload* pl; switch(cbor_value_get_type(&repMap)) { case CborNullType: err = !OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: err = err || cbor_value_get_int64(&repMap, &intval); if (!err) { err = !OCRepPayloadSetPropInt(curPayload, name, intval); } break; case CborDoubleType: err = err || cbor_value_get_double(&repMap, &doubleval); if (!err) { err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval); } break; case CborBooleanType: err = err || cbor_value_get_boolean(&repMap, &boolval); if (!err) { err = !OCRepPayloadSetPropBool(curPayload, name, boolval); } break; case CborTextStringType: err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL); if (!err) { err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } break; case CborMapType: err = err || OCParseSingleRepPayload(&pl, &repMap); if (!err) { err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } break; case CborArrayType: err = err || OCParseArray(curPayload, name, &repMap); break; default: OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); err = true; } err = err || cbor_value_advance(&repMap); OICFree(name); } err = err || cbor_value_leave_container(&curVal, &repMap); } if(err) { OCRepPayloadDestroy(*outPayload); *outPayload = NULL; } return err; }
CborError sol_oic_decode_cbor_repr_map(CborValue *map, struct sol_vector *reprs) { struct sol_oic_repr_field *repr; CborValue value; CborError err; size_t len; if (!cbor_value_is_map(map)) return CborInvalidType; err = cbor_value_enter_container(map, &value); for (; cbor_value_is_valid(&value) && err == CborNoError; err |= cbor_value_advance(&value)) { repr = sol_vector_append(reprs); if (!repr) return CborErrorOutOfMemory; err |= cbor_value_dup_text_string(&value, (char **)&repr->key, &len, NULL); err |= cbor_value_advance(&value); switch (cbor_value_get_type(&value)) { case CborIntegerType: err |= cbor_value_get_int64(&value, &repr->v_int); repr->type = SOL_OIC_REPR_TYPE_INT; break; case CborTextStringType: err |= cbor_value_dup_text_string(&value, (char **)&repr->v_slice.data, &repr->v_slice.len, NULL); if (err != CborNoError) goto harmless; repr->type = SOL_OIC_REPR_TYPE_TEXT_STRING; break; case CborByteStringType: err |= cbor_value_dup_byte_string(&value, (uint8_t **)&repr->v_slice.data, &repr->v_slice.len, NULL); if (err != CborNoError) goto harmless; repr->type = SOL_OIC_REPR_TYPE_BYTE_STRING; break; case CborDoubleType: err |= cbor_value_get_double(&value, &repr->v_double); repr->type = SOL_OIC_REPR_TYPE_DOUBLE; break; case CborFloatType: err |= cbor_value_get_float(&value, &repr->v_float); repr->type = SOL_OIC_REPR_TYPE_FLOAT; break; case CborHalfFloatType: err |= cbor_value_get_half_float(&value, &repr->v_voidptr); repr->type = SOL_OIC_REPR_TYPE_HALF_FLOAT; break; case CborBooleanType: err |= cbor_value_get_boolean(&value, &repr->v_boolean); repr->type = SOL_OIC_REPR_TYPE_BOOLEAN; break; default: SOL_ERR("While parsing representation map, got unexpected type %d", cbor_value_get_type(&value)); if (err == CborNoError) err = CborErrorUnknownType; harmless: /* Initialize repr with harmless data so cleanup works. */ repr->v_boolean = false; repr->type = SOL_OIC_REPR_TYPE_BOOLEAN; } } return err | cbor_value_leave_container(map, &value); }
static int cbor_internal_read_object(CborValue *root_value, const struct cbor_attr_t *attrs, const struct cbor_array_t *parent, int offset) { const struct cbor_attr_t *cursor, *best_match; char attrbuf[MYNEWT_VAL(CBORATTR_MAX_SIZE) + 1]; void *lptr; CborValue cur_value; CborError err = 0; size_t len; CborType type = CborInvalidType; /* stuff fields with defaults in case they're omitted in the JSON input */ for (cursor = attrs; cursor->attribute != NULL; cursor++) { if (!cursor->nodefault) { lptr = cbor_target_address(cursor, parent, offset); if (lptr != NULL) { switch (cursor->type) { case CborAttrIntegerType: memcpy(lptr, &cursor->dflt.integer, sizeof(long long int)); break; case CborAttrUnsignedIntegerType: memcpy(lptr, &cursor->dflt.integer, sizeof(long long unsigned int)); break; case CborAttrBooleanType: memcpy(lptr, &cursor->dflt.boolean, sizeof(bool)); break; #if FLOAT_SUPPORT case CborAttrFloatType: memcpy(lptr, &cursor->dflt.fval, sizeof(float)); break; case CborAttrDoubleType: memcpy(lptr, &cursor->dflt.real, sizeof(double)); break; #endif default: break; } } } } if (cbor_value_is_map(root_value)) { err |= cbor_value_enter_container(root_value, &cur_value); } else { err |= CborErrorIllegalType; return err; } /* contains key value pairs */ while (cbor_value_is_valid(&cur_value) && !err) { /* get the attribute */ if (cbor_value_is_text_string(&cur_value)) { if (cbor_value_calculate_string_length(&cur_value, &len) == 0) { if (len > MYNEWT_VAL(CBORATTR_MAX_SIZE)) { err |= CborErrorDataTooLarge; break; } err |= cbor_value_copy_text_string(&cur_value, attrbuf, &len, NULL); } /* at least get the type of the next value so we can match the * attribute name and type for a perfect match */ err |= cbor_value_advance(&cur_value); if (cbor_value_is_valid(&cur_value)) { type = cbor_value_get_type(&cur_value); } else { err |= CborErrorIllegalType; break; } } else { attrbuf[0] = '\0'; type = cbor_value_get_type(&cur_value); } /* find this attribute in our list */ best_match = NULL; for (cursor = attrs; cursor->attribute != NULL; cursor++) { if (valid_attr_type(type, cursor->type)) { if (cursor->attribute == CBORATTR_ATTR_UNNAMED && attrbuf[0] == '\0') { best_match = cursor; } else if (strlen(cursor->attribute) == len && !memcmp(cursor->attribute, attrbuf, len)) { break; } } } if (!cursor->attribute && best_match) { cursor = best_match; } /* we found a match */ if (cursor->attribute != NULL) { lptr = cbor_target_address(cursor, parent, offset); switch (cursor->type) { case CborAttrNullType: /* nothing to do */ break; case CborAttrBooleanType: err |= cbor_value_get_boolean(&cur_value, lptr); break; case CborAttrIntegerType: err |= cbor_value_get_int64(&cur_value, lptr); break; case CborAttrUnsignedIntegerType: err |= cbor_value_get_uint64(&cur_value, lptr); break; #if FLOAT_SUPPORT case CborAttrFloatType: err |= cbor_value_get_float(&cur_value, lptr); break; case CborAttrDoubleType: err |= cbor_value_get_double(&cur_value, lptr); break; #endif case CborAttrByteStringType: { size_t len = cursor->len; err |= cbor_value_copy_byte_string(&cur_value, lptr, &len, NULL); *cursor->addr.bytestring.len = len; break; } case CborAttrTextStringType: { size_t len = cursor->len; err |= cbor_value_copy_text_string(&cur_value, lptr, &len, NULL); break; } case CborAttrArrayType: err |= cbor_read_array(&cur_value, &cursor->addr.array); continue; case CborAttrObjectType: err |= cbor_internal_read_object(&cur_value, cursor->addr.obj, NULL, 0); continue; default: err |= CborErrorIllegalType; } } cbor_value_advance(&cur_value); } if (!err) { /* that should be it for this container */ err |= cbor_value_leave_container(root_value, &cur_value); } return err; }
static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot) { CborError err = CborUnknownError; char *name = NULL; bool res; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap"); if (cbor_value_is_map(objMap)) { if (!*outPayload) { *outPayload = OCRepPayloadCreate(); if (!*outPayload) { return CborErrorOutOfMemory; } } OCRepPayload *curPayload = *outPayload; size_t len = 0; CborValue repMap; err = cbor_value_enter_container(objMap, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap"); while (!err && cbor_value_is_valid(&repMap)) { if (cbor_value_is_text_string(&repMap)) { err = cbor_value_dup_text_string(&repMap, &name, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map"); err = cbor_value_advance(&repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap"); if (name && isRoot && ((0 == strcmp(OC_RSRVD_HREF, name)) || (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) || (0 == strcmp(OC_RSRVD_INTERFACE, name)))) { err = cbor_value_advance(&repMap); OICFree(name); continue; } } CborType type = cbor_value_get_type(&repMap); switch (type) { case CborNullType: res = OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: { int64_t intval = 0; err = cbor_value_get_int64(&repMap, &intval); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value"); res = OCRepPayloadSetPropInt(curPayload, name, intval); } break; case CborDoubleType: { double doubleval = 0; err = cbor_value_get_double(&repMap, &doubleval); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value"); res = OCRepPayloadSetPropDouble(curPayload, name, doubleval); } break; case CborBooleanType: { bool boolval = false; err = cbor_value_get_boolean(&repMap, &boolval); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value"); res = OCRepPayloadSetPropBool(curPayload, name, boolval); } break; case CborTextStringType: { char *strval = NULL; err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value"); res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } break; case CborByteStringType: { uint8_t* bytestrval = NULL; err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value"); OCByteString tmp = {.bytes = bytestrval, .len = len}; res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp); } break; case CborMapType: { OCRepPayload *pl = NULL; err = OCParseSingleRepPayload(&pl, &repMap, false); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep"); res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } break; case CborArrayType: err = OCParseArray(curPayload, name, &repMap); break; default: OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); res = false; } if (type != CborArrayType) { err = (CborError) !res; } VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value"); if (type != CborMapType && cbor_value_is_valid(&repMap)) { err = cbor_value_advance(&repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap"); } OICFree(name); name = NULL; } if (cbor_value_is_container(objMap)) { err = cbor_value_leave_container(objMap, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container"); } return err; } exit: OICFree(name); OCRepPayloadDestroy(*outPayload); *outPayload = NULL; return err; }
static CborError OCParseArrayFillArray(const CborValue *parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray) { CborValue insideArray; size_t i = 0; char *tempStr = NULL; OCByteString ocByteStr = { .bytes = NULL, .len = 0}; size_t tempLen = 0; OCRepPayload *tempPl = NULL; size_t newdim[MAX_REP_ARRAY_DEPTH]; newdim[0] = dimensions[1]; newdim[1] = dimensions[2]; newdim[2] = 0; CborError err = cbor_value_enter_container(parent, &insideArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container"); while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray)) { bool noAdvance = false; if (cbor_value_get_type(&insideArray) != CborNullType) { switch (type) { case OCREP_PROP_INT: if (dimensions[1] == 0) { err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((int64_t*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_DOUBLE: if (dimensions[1] == 0) { err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((double*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_BOOL: if (dimensions[1] == 0) { err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((bool*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_STRING: if (dimensions[1] == 0) { err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL); ((char**)targetArray)[i] = tempStr; tempStr = NULL; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((char**)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_BYTE_STRING: if (dimensions[1] == 0) { err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes), &(ocByteStr.len), NULL); ((OCByteString*)targetArray)[i] = ocByteStr; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((OCByteString*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_OBJECT: if (dimensions[1] == 0) { err = OCParseSingleRepPayload(&tempPl, &insideArray, false); ((OCRepPayload**)targetArray)[i] = tempPl; tempPl = NULL; noAdvance = true; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])); } break; default: OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); err = CborErrorUnknownType; break; } VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload"); } ++i; if (!noAdvance && cbor_value_is_valid(&insideArray)) { err = cbor_value_advance(&insideArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray"); } } exit: return err; } static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container) { void *arr = NULL; OCRepPayloadPropType type; size_t dimensions[MAX_REP_ARRAY_DEPTH]; size_t dimTotal; size_t allocSize; bool res = true; CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type); VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear"); if (type == OCREP_PROP_NULL) { res = OCRepPayloadSetNull(out, name); err = (CborError) !res; VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value"); err = cbor_value_advance(container); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container"); return err; } dimTotal = calcDimTotal(dimensions); allocSize = getAllocSize(type); arr = OICCalloc(dimTotal, allocSize); VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed"); res = OCParseArrayFillArray(container, dimensions, type, arr); VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array"); switch (type) { case OCREP_PROP_INT: res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions); break; case OCREP_PROP_DOUBLE: res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions); break; case OCREP_PROP_BOOL: res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions); break; case OCREP_PROP_STRING: res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions); break; case OCREP_PROP_BYTE_STRING: res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions); break; case OCREP_PROP_OBJECT: res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions); break; default: OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); break; } err = (CborError) !res; VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter"); return CborNoError; exit: if (type == OCREP_PROP_STRING) { for(size_t i = 0; i < dimTotal; ++i) { OICFree(((char**)arr)[i]); } } if (type == OCREP_PROP_BYTE_STRING) { for(size_t i = 0; i < dimTotal; ++i) { OICFree(((OCByteString*)arr)[i].bytes); } } if (type == OCREP_PROP_OBJECT) { for(size_t i = 0; i < dimTotal; ++i) { OCRepPayloadDestroy(((OCRepPayload**)arr)[i]); } } OICFree(arr); return err; }