static int _icd_state_array_from_list(OCRepPayload *repr,
		struct icd_state_list_s *value_list, const char *key)
{
	int i, len;
	GList *node;
	bool *b_arr;
	double *d_arr;
	char **str_arr;
	int64_t *i_arr;
	OCByteString *byte_arr;
	union icd_state_value_u *value;
	struct OCRepPayload **state_arr;

	len = calcDimTotal(value_list->dimensions);

	switch (value_list->type) {
	case OCREP_PROP_INT:
		i_arr = calloc(len, sizeof(int64_t));
		if (NULL == i_arr) {
			ERR("calloc() Fail(%d)", errno);
			return IOTCON_ERROR_OUT_OF_MEMORY;
		}
		for (node = value_list->list, i = 0; node; node = node->next, i++) {
			value = node->data;
			i_arr[i] = value->i;
		}
		g_list_free_full(value_list->list, free);
		OCRepPayloadSetIntArrayAsOwner(repr, key, i_arr, value_list->dimensions);
		break;
	case OCREP_PROP_BOOL:
		b_arr = calloc(len, sizeof(bool));
		if (NULL == b_arr) {
			ERR("calloc() Fail(%d)", errno);
			return IOTCON_ERROR_OUT_OF_MEMORY;
		}
		for (node = value_list->list, i = 0; node; node = node->next, i++) {
			value = node->data;
			b_arr[i] = value->b;
		}
		g_list_free_full(value_list->list, free);
		OCRepPayloadSetBoolArrayAsOwner(repr, key, b_arr, value_list->dimensions);
		break;
	case OCREP_PROP_DOUBLE:
		d_arr = calloc(len, sizeof(double));
		if (NULL == d_arr) {
			ERR("calloc() Fail(%d)", errno);
			return IOTCON_ERROR_OUT_OF_MEMORY;
		}
		for (node = value_list->list, i = 0; node; node = node->next, i++) {
			value = node->data;
			d_arr[i] = value->d;
		}
		g_list_free_full(value_list->list, free);
		OCRepPayloadSetDoubleArrayAsOwner(repr, key, d_arr, value_list->dimensions);
		break;
	case OCREP_PROP_STRING:
		str_arr = calloc(len, sizeof(char *));
		if (NULL == str_arr) {
			ERR("calloc() Fail(%d)", errno);
			return IOTCON_ERROR_OUT_OF_MEMORY;
		}
		for (node = value_list->list, i = 0; node; node = node->next, i++)
			str_arr[i] = strdup(node->data);
		g_list_free_full(value_list->list, free);
		OCRepPayloadSetStringArrayAsOwner(repr, key, str_arr, value_list->dimensions);
		break;
	case OCREP_PROP_BYTE_STRING:
		byte_arr = calloc(len, sizeof(OCByteString));
		if (NULL == byte_arr) {
			ERR("calloc() Fail(%d)", errno);
			return IOTCON_ERROR_OUT_OF_MEMORY;
		}
		for (node = value_list->list, i = 0; node; node = node->next, i++) {
			OCByteString *byte_str = node->data;
			byte_arr[i].bytes = byte_str->bytes;
			byte_arr[i].len = byte_str->len;
		}
		g_list_free(value_list->list);
		OCRepPayloadSetByteStringArray(repr, key, byte_arr, value_list->dimensions);

		break;
	case OCREP_PROP_OBJECT:
		state_arr = calloc(len, sizeof(struct OCRepPayload *));
		if (NULL == state_arr) {
			ERR("calloc() Fail(%d)", errno);
			return IOTCON_ERROR_OUT_OF_MEMORY;
		}
		for (node = value_list->list, i = 0; node; node = node->next, i++)
			state_arr[i] = OCRepPayloadClone(node->data);
		g_list_free_full(value_list->list, _icd_payload_object_destroy);
		OCRepPayloadSetPropObjectArrayAsOwner(repr, key, state_arr,
				value_list->dimensions);
		break;
	case OCREP_PROP_ARRAY:
	case OCREP_PROP_NULL:
	default:
		ERR("Invalid Type(%d)", value_list->type);
		return IOTCON_ERROR_INVALID_TYPE;
	}

	return IOTCON_ERROR_NONE;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 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;
}