Exemplo n.º 1
0
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;
}
Exemplo 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;
        }
    }
Exemplo 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;
}
Exemplo 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;
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}