Esempio n. 1
0
static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
{
    if (!outPayload)
    {
        return OC_STACK_INVALID_PARAM;
    }

    bool err = false;

    OCRepPayload* rootPayload = NULL;
    OCRepPayload* curPayload = NULL;
    OCRepPayload* temp = NULL;
    while(!err && cbor_value_is_map(arrayVal))
    {
         err = err || OCParseSingleRepPayload(&temp, arrayVal);

        if(rootPayload == NULL)
        {
            rootPayload = temp;
            curPayload = temp;
        }
        else
        {
            curPayload->next = temp;
            curPayload = curPayload->next;
        }


         err = err || cbor_value_advance(arrayVal);
        if(err)
        {
            OCRepPayloadDestroy(rootPayload);
            OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
            return OC_STACK_MALFORMED_RESPONSE;
        }
    }

    *outPayload = (OCPayload*)rootPayload;

    return OC_STACK_OK;
}
Esempio n. 2
0
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;
        }
    }
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
{
    OCStackResult ret = OC_STACK_INVALID_PARAM;
    CborError err;
    OCRepPayload *temp = NULL;
    OCRepPayload *rootPayload = NULL;
    OCRepPayload *curPayload = NULL;
    CborValue rootMap = *root;
    VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
    VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");

    *outPayload = NULL;
    if (cbor_value_is_array(root))
    {
        err = cbor_value_enter_container(root, &rootMap);
    }
    while (cbor_value_is_valid(&rootMap))
    {
        temp = OCRepPayloadCreate();
        ret = OC_STACK_NO_MEMORY;
        VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");

        CborValue curVal;
        ret = OC_STACK_MALFORMED_RESPONSE;

        if (cbor_value_is_map(&rootMap))
        {
            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
            if (cbor_value_is_valid(&curVal))
            {
                size_t len = 0;
                err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
                VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
            }
        }
        // Resource types
        if (cbor_value_is_map(&rootMap))
        {
            if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
            {
                err =  OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
                VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
            }
        }

        // Interface Types
        if (cbor_value_is_map(&rootMap))
        {
            if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
            {
                err =  OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
                VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
            }
        }

        if (cbor_value_is_map(&rootMap))
        {
            err = OCParseSingleRepPayload(&temp, &rootMap, true);
            VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
        }
        if(rootPayload == NULL)
        {
            rootPayload = temp;
            curPayload = temp;
        }
        else
        {
            curPayload->next = temp;
            curPayload = curPayload->next;
        }

        if (cbor_value_is_array(&rootMap))
        {
            err = cbor_value_advance(&rootMap);
            VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
        }
    }
    *outPayload = (OCPayload *)rootPayload;
    return OC_STACK_OK;

exit:
    OCRepPayloadDestroy(temp);
    OCRepPayloadDestroy(rootPayload);
    OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
    return ret;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}