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 OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
{
    OCRepPayloadPropType type;
    size_t dimensions[MAX_REP_ARRAY_DEPTH];
    bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);

    if (err)
    {
        OC_LOG(ERROR, TAG, "Array details weren't clear");
        return err;
    }

    if (type == OCREP_PROP_NULL)
    {
        err = err || OCRepPayloadSetNull(out, name);
        err = err || cbor_value_advance(container);
        return err;
    }

    size_t dimTotal = calcDimTotal(dimensions);
    size_t allocSize = getAllocSize(type);
    void* arr = OICCalloc(dimTotal, allocSize);

    if (!arr)
    {
        OC_LOG(ERROR, TAG, "Array Parse allocation failed");
        return true;
    }

    err = err || OCParseArrayFillArray(container, dimensions, type, arr);

    switch (type)
    {
    case OCREP_PROP_INT:
        if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
        {
            OICFree(arr);
            err = true;
        }
        break;
    case OCREP_PROP_DOUBLE:
        if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
        {
            OICFree(arr);
            err = true;
        }
        break;
    case OCREP_PROP_BOOL:
        if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
        {
            OICFree(arr);
            err = true;
        }
        break;
    case OCREP_PROP_STRING:
        if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
        {
            for(size_t i = 0; i < dimTotal; ++i)
            {
                OICFree(((char**)arr)[i]);
            }
            OICFree(arr);
            err = true;
        }
        break;
    case OCREP_PROP_OBJECT:
        if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
        {
            for(size_t i = 0; i < dimTotal; ++i)
            {
                OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
            }
            OICFree(arr);
            err = true;
        }
        break;
    default:
        OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
        err = true;
        break;
    }

    return err;
}
Exemple #3
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;
}