mirror of
https://github.com/Telecominfraproject/oopt-tai.git
synced 2025-12-30 18:10:58 +00:00
This reverts commit 1955bb551d.
The commit breaks existing TAI libraries
Signed-off-by: Wataru Ishida <wataru.ishid@gmail.com>
1038 lines
34 KiB
C
1038 lines
34 KiB
C
/**
|
|
* @file taimetadatautils.c
|
|
*
|
|
* @brief This module implements TAI Metadata Utilities
|
|
*
|
|
* @copyright Copyright (c) 2014 Microsoft Open Technologies, Inc.
|
|
* @copyright Copyright (c) 2018 Nippon Telegraph and Telephone Corporation
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* This source code includes software licensed by Microsoft under the
|
|
* Apache License, Version 2.0
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <tai.h>
|
|
#include "taimetadatautils.h"
|
|
#include "taimetadata.h"
|
|
|
|
bool tai_metadata_is_allowed_object_type(
|
|
_In_ const tai_attr_metadata_t* metadata,
|
|
_In_ tai_object_type_t object_type)
|
|
{
|
|
if (metadata == NULL || metadata->allowedobjecttypes == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
size_t i = 0;
|
|
|
|
for (; i < metadata->allowedobjecttypeslength; ++i)
|
|
{
|
|
if (metadata->allowedobjecttypes[i] == object_type)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool tai_metadata_is_allowed_enum_value(
|
|
_In_ const tai_attr_metadata_t* metadata,
|
|
_In_ int value)
|
|
{
|
|
if (metadata == NULL || metadata->enummetadata == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
size_t i = 0;
|
|
|
|
const tai_enum_metadata_t *emd = metadata->enummetadata;
|
|
|
|
for (; i < emd->valuescount; ++i)
|
|
{
|
|
if (emd->values[i] == value)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
const tai_attr_metadata_t* tai_metadata_get_attr_metadata(
|
|
_In_ tai_object_type_t objecttype,
|
|
_In_ tai_attr_id_t attrid)
|
|
{
|
|
if (tai_metadata_is_object_type_valid(objecttype))
|
|
{
|
|
const tai_attr_metadata_t* const* const md = tai_metadata_attr_by_object_type[objecttype];
|
|
|
|
/*
|
|
* Most object attributes are not flags, so we can use direct index to
|
|
* find attribute metadata, this should speed up search.
|
|
*/
|
|
|
|
const tai_object_type_info_t* oi = tai_metadata_all_object_type_infos[objecttype];
|
|
|
|
if (!oi->enummetadata->containsflags && attrid < oi->enummetadata->valuescount)
|
|
{
|
|
return md[attrid];
|
|
}
|
|
|
|
/* otherwise search one by one */
|
|
|
|
size_t index = 0;
|
|
|
|
for (; md[index] != NULL; index++)
|
|
{
|
|
if (md[index]->attrid == attrid)
|
|
{
|
|
return md[index];
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const tai_attr_metadata_t* tai_metadata_get_attr_metadata_by_attr_id_name(
|
|
_In_ const char *attr_id_name)
|
|
{
|
|
if (attr_id_name == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/* use binary search */
|
|
|
|
ssize_t first = 0;
|
|
ssize_t last = (ssize_t)(tai_metadata_attr_sorted_by_id_name_count - 1);
|
|
|
|
while (first <= last)
|
|
{
|
|
ssize_t middle = (first + last) / 2;
|
|
|
|
int res = strcmp(attr_id_name, tai_metadata_attr_sorted_by_id_name[middle]->attridname);
|
|
|
|
if (res > 0)
|
|
{
|
|
first = middle + 1;
|
|
}
|
|
else if (res < 0)
|
|
{
|
|
last = middle - 1;
|
|
}
|
|
else
|
|
{
|
|
/* found */
|
|
|
|
return tai_metadata_attr_sorted_by_id_name[middle];
|
|
}
|
|
}
|
|
|
|
/* not found */
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char* tai_metadata_get_enum_value_name(
|
|
_In_ const tai_enum_metadata_t* metadata,
|
|
_In_ int value)
|
|
{
|
|
if (metadata == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
size_t i = 0;
|
|
|
|
for (; i < metadata->valuescount; ++i)
|
|
{
|
|
if (metadata->values[i] == value)
|
|
{
|
|
return metadata->valuesnames[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const tai_attribute_t* tai_metadata_get_attr_by_id(
|
|
_In_ tai_attr_id_t id,
|
|
_In_ uint32_t attr_count,
|
|
_In_ const tai_attribute_t *attr_list)
|
|
{
|
|
if (attr_list == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
uint32_t i = 0;
|
|
|
|
for (; i < attr_count; ++i)
|
|
{
|
|
if (attr_list[i].id == id)
|
|
{
|
|
return &attr_list[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const tai_object_type_info_t* tai_metadata_get_object_type_info(
|
|
_In_ tai_object_type_t object_type)
|
|
{
|
|
if (tai_metadata_is_object_type_valid(object_type))
|
|
{
|
|
return tai_metadata_all_object_type_infos[object_type];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool tai_metadata_is_object_type_valid(
|
|
_In_ tai_object_type_t object_type)
|
|
{
|
|
return object_type > TAI_OBJECT_TYPE_NULL && object_type < TAI_OBJECT_TYPE_MAX;
|
|
}
|
|
|
|
bool tai_metadata_is_condition_met(
|
|
_In_ const tai_attr_metadata_t *metadata,
|
|
_In_ uint32_t attr_count,
|
|
_In_ const tai_attribute_t *attr_list)
|
|
{
|
|
if (metadata == NULL || !metadata->isconditional || attr_list == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
size_t idx = 0;
|
|
|
|
bool met = (metadata->conditiontype == TAI_ATTR_CONDITION_TYPE_AND);
|
|
|
|
for (; idx < metadata->conditionslength; ++idx)
|
|
{
|
|
const tai_attr_condition_t *condition = metadata->conditions[idx];
|
|
|
|
/*
|
|
* Conditons may only be on the same object type.
|
|
*
|
|
* Default value may not exists if conditional object is marked as
|
|
* MANDATORY_ON_CREATE.
|
|
*/
|
|
|
|
const tai_attr_metadata_t *cmd = tai_metadata_get_attr_metadata(metadata->objecttype, condition->attrid);
|
|
|
|
const tai_attribute_t *cattr = tai_metadata_get_attr_by_id(condition->attrid, attr_count, attr_list);
|
|
|
|
const tai_attribute_value_t* cvalue = NULL;
|
|
|
|
if (cattr == NULL)
|
|
{
|
|
/*
|
|
* User didn't passed conditional attribute, so check if there is
|
|
* default value.
|
|
*/
|
|
|
|
cvalue = cmd->defaultvalue;
|
|
}
|
|
else
|
|
{
|
|
cvalue = &cattr->value;
|
|
}
|
|
|
|
if (cvalue == NULL)
|
|
{
|
|
/*
|
|
* There is no default value and user didn't passed attribute.
|
|
*/
|
|
|
|
if (metadata->conditiontype == TAI_ATTR_CONDITION_TYPE_AND)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
bool current = false;
|
|
|
|
switch (cmd->attrvaluetype)
|
|
{
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
current = (condition->condition.booldata == cvalue->booldata);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
current = (condition->condition.s8 == cvalue->s8);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
current = (condition->condition.s16 == cvalue->s16);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
current = (condition->condition.s32 == cvalue->s32);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
current = (condition->condition.s64 == cvalue->s64);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
current = (condition->condition.u8 == cvalue->u8);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
current = (condition->condition.u16 == cvalue->u16);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
current = (condition->condition.u32 == cvalue->u32);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
current = (condition->condition.u64 == cvalue->u64);
|
|
break;
|
|
|
|
default:
|
|
|
|
/*
|
|
* We should never get here since sanity check tests all
|
|
* attributes and all conditions.
|
|
*/
|
|
|
|
TAI_META_LOG_ERROR("condition value type %d is not supported, FIXME", cmd->attrvaluetype);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (metadata->conditiontype == TAI_ATTR_CONDITION_TYPE_AND)
|
|
{
|
|
met &= current;
|
|
}
|
|
else /* OR */
|
|
{
|
|
met |= current;
|
|
}
|
|
}
|
|
|
|
return met;
|
|
}
|
|
|
|
#define DEFAULT_LIST_SIZE 16
|
|
|
|
#define _TAI_META_ALLOC_LIST(valuename, type)\
|
|
value->valuename.count = size;\
|
|
value->valuename.list = realloc(value->valuename.list, size * sizeof(type));\
|
|
if ( value->valuename.list == NULL ) {\
|
|
return TAI_STATUS_NO_MEMORY;\
|
|
}\
|
|
|
|
#define _TAI_META_FREE_LIST(valuename)\
|
|
value->valuename.count = 0;\
|
|
free(value->valuename.list);\
|
|
value->valuename.list = NULL;\
|
|
|
|
#define _TAI_META_COPY_LIST(valuename, type)\
|
|
if( out->valuename.count < in->valuename.count ) {\
|
|
out->valuename.count = in->valuename.count;\
|
|
return TAI_STATUS_BUFFER_OVERFLOW;\
|
|
}\
|
|
out->valuename.count = in->valuename.count;\
|
|
memcpy(out->valuename.list, in->valuename.list, sizeof(type) * in->valuename.count);
|
|
|
|
#define _TAI_META_CMP(result, valuename) \
|
|
*result = ( lhs->value.valuename == rhs->value.valuename );\
|
|
break;
|
|
|
|
#define _TAI_META_LE(result, valuename) \
|
|
*result = ( lhs->value.valuename <= rhs->value.valuename );\
|
|
break;
|
|
|
|
#define _TAI_META_GE(result, valuename) \
|
|
*result = ( lhs->value.valuename >= rhs->value.valuename );\
|
|
break;
|
|
|
|
#define _TAI_META_CMP_LIST(result, valuename) \
|
|
{ \
|
|
if( lhs->value.valuename.count != rhs->value.valuename.count ) { \
|
|
*result = false; \
|
|
return TAI_STATUS_SUCCESS; \
|
|
} \
|
|
for ( int i = 0; i < lhs->value.valuename.count; i++ ) { \
|
|
if ( lhs->value.valuename.list[i] != rhs->value.valuename.list[i] ) { \
|
|
*result = false; \
|
|
return TAI_STATUS_SUCCESS; \
|
|
} \
|
|
} \
|
|
*result = true; \
|
|
} \
|
|
break;
|
|
|
|
tai_status_t _tai_metadata_free_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ tai_attribute_value_t* const value,
|
|
_In_ const tai_alloc_info_t* const info) {
|
|
if ( metadata == NULL || value == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
int i;
|
|
tai_attr_metadata_t m = *metadata;
|
|
m.attrvaluetype = m.attrlistvaluetype;
|
|
m.attrlistvaluetype = TAI_ATTR_VALUE_TYPE_UNSPECIFIED;
|
|
|
|
switch( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
case TAI_ATTR_VALUE_TYPE_CHARDATA:
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
case TAI_ATTR_VALUE_TYPE_PTR:
|
|
case TAI_ATTR_VALUE_TYPE_OID:
|
|
case TAI_ATTR_VALUE_TYPE_U32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_S32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
|
|
return TAI_STATUS_SUCCESS;
|
|
case TAI_ATTR_VALUE_TYPE_OBJLIST:
|
|
_TAI_META_FREE_LIST(objlist);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_CHARLIST:
|
|
_TAI_META_FREE_LIST(charlist);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U8LIST:
|
|
_TAI_META_FREE_LIST(u8list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S8LIST:
|
|
_TAI_META_FREE_LIST(s8list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U16LIST:
|
|
_TAI_META_FREE_LIST(u16list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S16LIST:
|
|
_TAI_META_FREE_LIST(s16list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U32LIST:
|
|
_TAI_META_FREE_LIST(u32list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S32LIST:
|
|
_TAI_META_FREE_LIST(s32list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U64LIST:
|
|
_TAI_META_FREE_LIST(u64list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S64LIST:
|
|
_TAI_META_FREE_LIST(s64list);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_FLOATLIST:
|
|
_TAI_META_FREE_LIST(floatlist);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
|
|
// we must use alloced field instead of count field since
|
|
// count field is not always equal to the allocated number
|
|
for ( i = 0; i < value->objmaplist._alloced; i++ ) {
|
|
value->objmaplist.list[i].value.count = 0;
|
|
free(value->objmaplist.list[i].value.list);
|
|
value->objmaplist.list[i].value.list = NULL;
|
|
}
|
|
_TAI_META_FREE_LIST(objmaplist);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_ATTRLIST:
|
|
// we must use alloced field instead of count field since
|
|
// count field is not always equal to the allocated number
|
|
for ( i = 0; i < value->attrlist._alloced; i++ ) {
|
|
if ( _tai_metadata_free_attr_value(&m, &value->attrlist.list[i], info) < 0 ) {
|
|
return TAI_STATUS_FAILURE;
|
|
}
|
|
}
|
|
_TAI_META_FREE_LIST(attrlist);
|
|
break;
|
|
default:
|
|
TAI_META_LOG_ERROR("unsupported value type: %d", metadata->attrvaluetype);
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
|
|
static tai_status_t _tai_metadata_clear_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ tai_attribute_value_t* const value) {
|
|
if ( metadata == NULL || value == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
switch( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
case TAI_ATTR_VALUE_TYPE_CHARDATA:
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
case TAI_ATTR_VALUE_TYPE_PTR:
|
|
case TAI_ATTR_VALUE_TYPE_OID:
|
|
case TAI_ATTR_VALUE_TYPE_U32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_S32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
|
|
memset(value, 0, sizeof(tai_attribute_value_t));
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJLIST:
|
|
value->objlist.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_CHARLIST:
|
|
value->charlist.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U8LIST:
|
|
value->u8list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S8LIST:
|
|
value->s8list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U16LIST:
|
|
value->u16list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S16LIST:
|
|
value->s16list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U32LIST:
|
|
value->u32list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S32LIST:
|
|
value->s32list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U64LIST:
|
|
value->u64list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S64LIST:
|
|
value->s64list.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_FLOATLIST:
|
|
value->floatlist.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
|
|
value->objmaplist.count = 0;
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_ATTRLIST:
|
|
value->attrlist.count = 0;
|
|
break;
|
|
default:
|
|
TAI_META_LOG_ERROR("unsupported value type: %d", metadata->attrvaluetype);
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
|
|
static int _tai_list_size(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ const tai_attribute_value_t* const value) {
|
|
|
|
switch( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
case TAI_ATTR_VALUE_TYPE_CHARDATA:
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
case TAI_ATTR_VALUE_TYPE_PTR:
|
|
case TAI_ATTR_VALUE_TYPE_OID:
|
|
case TAI_ATTR_VALUE_TYPE_U32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_S32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
|
|
return 0;
|
|
case TAI_ATTR_VALUE_TYPE_OBJLIST:
|
|
return value->objlist.count;
|
|
case TAI_ATTR_VALUE_TYPE_CHARLIST:
|
|
return value->charlist.count;
|
|
case TAI_ATTR_VALUE_TYPE_U8LIST:
|
|
return value->u8list.count;
|
|
case TAI_ATTR_VALUE_TYPE_S8LIST:
|
|
return value->s8list.count;
|
|
case TAI_ATTR_VALUE_TYPE_U16LIST:
|
|
return value->u16list.count;
|
|
case TAI_ATTR_VALUE_TYPE_S16LIST:
|
|
return value->s16list.count;
|
|
case TAI_ATTR_VALUE_TYPE_U32LIST:
|
|
return value->u32list.count;
|
|
case TAI_ATTR_VALUE_TYPE_S32LIST:
|
|
return value->s32list.count;
|
|
case TAI_ATTR_VALUE_TYPE_U64LIST:
|
|
return value->u64list.count;
|
|
case TAI_ATTR_VALUE_TYPE_S64LIST:
|
|
return value->s64list.count;
|
|
case TAI_ATTR_VALUE_TYPE_FLOATLIST:
|
|
return value->floatlist.count;
|
|
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
|
|
return value->objmaplist.count;
|
|
case TAI_ATTR_VALUE_TYPE_ATTRLIST:
|
|
return value->attrlist.count;
|
|
default:
|
|
TAI_META_LOG_ERROR("unsupported value type: %d", metadata->attrvaluetype);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
static tai_status_t _tai_metadata_alloc_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ tai_attribute_value_t* const value,
|
|
_In_ const tai_alloc_info_t* const info) {
|
|
if ( metadata == NULL || value == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
int size = DEFAULT_LIST_SIZE, i, j;
|
|
if ( info != NULL ) {
|
|
size = info->list_size;
|
|
if ( info->reference != NULL ) {
|
|
size = _tai_list_size(metadata, &info->reference->value);
|
|
}
|
|
}
|
|
if ( size == 0 ) {
|
|
size = DEFAULT_LIST_SIZE;
|
|
}
|
|
switch( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
case TAI_ATTR_VALUE_TYPE_CHARDATA:
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
case TAI_ATTR_VALUE_TYPE_PTR:
|
|
case TAI_ATTR_VALUE_TYPE_OID:
|
|
case TAI_ATTR_VALUE_TYPE_U32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_S32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
|
|
return TAI_STATUS_SUCCESS;
|
|
case TAI_ATTR_VALUE_TYPE_OBJLIST:
|
|
_TAI_META_ALLOC_LIST(objlist, tai_object_id_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_CHARLIST:
|
|
_TAI_META_ALLOC_LIST(charlist, char);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U8LIST:
|
|
_TAI_META_ALLOC_LIST(u8list, uint8_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S8LIST:
|
|
_TAI_META_ALLOC_LIST(s8list, int8_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U16LIST:
|
|
_TAI_META_ALLOC_LIST(u16list, uint16_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S16LIST:
|
|
_TAI_META_ALLOC_LIST(s16list, int16_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U32LIST:
|
|
_TAI_META_ALLOC_LIST(u32list, uint32_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S32LIST:
|
|
_TAI_META_ALLOC_LIST(s32list, int32_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U64LIST:
|
|
_TAI_META_ALLOC_LIST(u64list, uint64_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S64LIST:
|
|
_TAI_META_ALLOC_LIST(s64list, int64_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_FLOATLIST:
|
|
_TAI_META_ALLOC_LIST(floatlist, float);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
|
|
_TAI_META_ALLOC_LIST(objmaplist, tai_object_map_list_t);
|
|
value->attrlist._alloced = size;
|
|
for ( i = 0; i < size; i++ ) {
|
|
int ssize = size;
|
|
if ( info != NULL && info->reference != NULL ) {
|
|
int s = 0;
|
|
if ( info->reference->value.objmaplist.count > i ) {
|
|
s = info->reference->value.objmaplist.list[i].value.count;
|
|
}
|
|
ssize = (s > 0) ? s : DEFAULT_LIST_SIZE;
|
|
}
|
|
value->objmaplist.list[i].value.count = ssize;
|
|
value->objmaplist.list[i].value.list = calloc(ssize, sizeof(tai_object_map_t));
|
|
if ( value->objmaplist.list[i].value.list == NULL ) {
|
|
for ( j = 0; j < i; j++ ) {
|
|
free(value->objmaplist.list[j].value.list);
|
|
value->objmaplist.list[j].value.list = NULL;
|
|
value->objmaplist.list[j].value.count = 0;
|
|
}
|
|
_TAI_META_FREE_LIST(objmaplist);
|
|
value->attrlist._alloced = 0;
|
|
return TAI_STATUS_NO_MEMORY;
|
|
}
|
|
}
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_ATTRLIST:
|
|
{
|
|
_TAI_META_ALLOC_LIST(attrlist, tai_attribute_value_t);
|
|
memset(value->attrlist.list, 0, size * sizeof(tai_attribute_value_t));\
|
|
value->attrlist._alloced = size;
|
|
|
|
tai_attr_metadata_t nested_meta = *metadata;
|
|
nested_meta.attrvaluetype = nested_meta.attrlistvaluetype;
|
|
nested_meta.attrlistvaluetype = TAI_ATTR_VALUE_TYPE_UNSPECIFIED;
|
|
|
|
for ( i = 0; i < size; i++ ) {
|
|
int ssize = size;
|
|
if ( info != NULL && info->reference != NULL ) {
|
|
int s = _tai_list_size(&nested_meta, &info->reference->value.attrlist.list[i]);
|
|
ssize = (s > 0) ? s : DEFAULT_LIST_SIZE;
|
|
}
|
|
tai_alloc_info_t nested_info = { .list_size = ssize };
|
|
if ( _tai_metadata_alloc_attr_value(&nested_meta, &(value->attrlist.list[i]), &nested_info) < 0 ) {
|
|
for ( j = 0; j < i; j++ ) {
|
|
_tai_metadata_free_attr_value(&nested_meta, &value->attrlist.list[j], &nested_info);
|
|
}
|
|
_TAI_META_FREE_LIST(attrlist);
|
|
value->attrlist._alloced = 0;
|
|
return TAI_STATUS_NO_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
TAI_META_LOG_ERROR("unsupported value type: %d", metadata->attrvaluetype);
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
|
|
tai_status_t tai_metadata_alloc_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ tai_attribute_t* const attr,
|
|
_In_ const tai_alloc_info_t* const info) {
|
|
if ( attr == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
return _tai_metadata_alloc_attr_value(metadata, &attr->value, info);
|
|
}
|
|
|
|
tai_status_t tai_metadata_free_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ tai_attribute_t* const attr,
|
|
_In_ const tai_alloc_info_t* const info) {
|
|
if ( attr == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
return _tai_metadata_free_attr_value(metadata, &attr->value, info);
|
|
}
|
|
|
|
tai_status_t tai_metadata_clear_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ tai_attribute_t* const attr) {
|
|
if ( attr == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
return _tai_metadata_clear_attr_value(metadata, &attr->value);
|
|
}
|
|
|
|
static tai_status_t _tai_metadata_deepcopy_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ const tai_attribute_value_t* const in,
|
|
_Out_ tai_attribute_value_t* const out) {
|
|
if ( metadata == NULL || in == NULL || out == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
tai_attr_metadata_t m = *metadata;
|
|
m.attrvaluetype = m.attrlistvaluetype;
|
|
m.attrlistvaluetype = TAI_ATTR_VALUE_TYPE_UNSPECIFIED;
|
|
|
|
int i;
|
|
tai_status_t ret;
|
|
switch( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
case TAI_ATTR_VALUE_TYPE_CHARDATA:
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
case TAI_ATTR_VALUE_TYPE_PTR:
|
|
case TAI_ATTR_VALUE_TYPE_OID:
|
|
case TAI_ATTR_VALUE_TYPE_U32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_S32RANGE:
|
|
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
|
|
memcpy(out, in, sizeof(tai_attribute_value_t));
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJLIST:
|
|
_TAI_META_COPY_LIST(objlist, tai_object_id_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_CHARLIST:
|
|
_TAI_META_COPY_LIST(charlist, char);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U8LIST:
|
|
_TAI_META_COPY_LIST(u8list, uint8_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S8LIST:
|
|
_TAI_META_COPY_LIST(s8list, int8_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U16LIST:
|
|
_TAI_META_COPY_LIST(u16list, uint16_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S16LIST:
|
|
_TAI_META_COPY_LIST(s16list, int16_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U32LIST:
|
|
_TAI_META_COPY_LIST(u32list, uint32_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S32LIST:
|
|
_TAI_META_COPY_LIST(s32list, int32_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U64LIST:
|
|
_TAI_META_COPY_LIST(u64list, uint64_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S64LIST:
|
|
_TAI_META_COPY_LIST(s64list, int64_t);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_FLOATLIST:
|
|
_TAI_META_COPY_LIST(floatlist, float);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
|
|
if( out->objmaplist.count < in->objmaplist.count ) {
|
|
out->objmaplist.count = in->objmaplist.count;
|
|
return TAI_STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
out->objmaplist.count = in->objmaplist.count;
|
|
for ( i = 0; i < in->objmaplist.count ; i++ ) {
|
|
if ( out->objmaplist.list[i].value.count < in->objmaplist.list[i].value.count ) {
|
|
out->objmaplist.list[i].value.count = in->objmaplist.list[i].value.count;
|
|
return TAI_STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
out->objmaplist.list[i].key = in->objmaplist.list[i].key;
|
|
out->objmaplist.list[i].value.count = in->objmaplist.list[i].value.count;
|
|
memcpy(out->objmaplist.list[i].value.list, in->objmaplist.list[i].value.list, sizeof(tai_object_map_t) * in->objmaplist.list[i].value.count);
|
|
}
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_ATTRLIST:
|
|
if( out->attrlist.count < in->attrlist.count ) {
|
|
out->attrlist.count = in->attrlist.count;
|
|
return TAI_STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
out->attrlist.count = in->attrlist.count;
|
|
for ( i = 0; i < in->attrlist.count; i++ ) {
|
|
ret = _tai_metadata_deepcopy_attr_value(&m, &in->attrlist.list[i], &out->attrlist.list[i]);
|
|
if ( ret != TAI_STATUS_SUCCESS ) {
|
|
return ret;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
TAI_META_LOG_ERROR("unsupported value type: %d", metadata->attrvaluetype);
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
|
|
tai_status_t tai_metadata_deepcopy_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ const tai_attribute_t* const in,
|
|
_Out_ tai_attribute_t* const out) {
|
|
if ( metadata == NULL || in == NULL || out == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
out->id = in->id;
|
|
return _tai_metadata_deepcopy_attr_value(metadata, &in->value, &out->value);
|
|
}
|
|
|
|
// if lhs <= rhs then result=1, else result=0
|
|
tai_status_t tai_metadata_le_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ const tai_attribute_t* const lhs,
|
|
_In_ const tai_attribute_t* const rhs,
|
|
_Out_ bool* result) {
|
|
if ( metadata == NULL || result == NULL || lhs == NULL || rhs == NULL || lhs->id != rhs->id ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
switch ( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
_TAI_META_LE(result, u8)
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
_TAI_META_LE(result, s8)
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
_TAI_META_LE(result, u16)
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
_TAI_META_LE(result, s16)
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
_TAI_META_LE(result, u32)
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
_TAI_META_LE(result, s32)
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
_TAI_META_LE(result, u64)
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
_TAI_META_LE(result, s64)
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
_TAI_META_LE(result, flt)
|
|
default:
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
|
|
// if lhs => rhs then result=1, else result=0
|
|
tai_status_t tai_metadata_ge_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ const tai_attribute_t* const lhs,
|
|
_In_ const tai_attribute_t* const rhs,
|
|
_Out_ bool* result) {
|
|
if ( metadata == NULL || result == NULL || lhs == NULL || rhs == NULL || lhs->id != rhs->id ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
switch ( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
_TAI_META_GE(result, u8)
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
_TAI_META_GE(result, s8)
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
_TAI_META_GE(result, u16)
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
_TAI_META_GE(result, s16)
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
_TAI_META_GE(result, u32)
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
_TAI_META_GE(result, s32)
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
_TAI_META_GE(result, u64)
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
_TAI_META_GE(result, s64)
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
_TAI_META_GE(result, flt)
|
|
default:
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
|
|
tai_status_t tai_metadata_deepequal_attr_value(
|
|
_In_ const tai_attr_metadata_t* const metadata,
|
|
_In_ const tai_attribute_t* const lhs,
|
|
_In_ const tai_attribute_t* const rhs,
|
|
_Out_ bool* result) {
|
|
if ( metadata == NULL || result == NULL ) {
|
|
return TAI_STATUS_INVALID_PARAMETER;
|
|
}
|
|
if ( (lhs == NULL && rhs != NULL) || (lhs != NULL && rhs == NULL) ) {
|
|
*result = false;
|
|
return TAI_STATUS_SUCCESS;
|
|
} else if ( lhs == NULL && rhs == NULL ) {
|
|
*result = true;
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
if ( lhs->id != rhs->id ) {
|
|
*result = false;
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
switch( metadata->attrvaluetype ) {
|
|
case TAI_ATTR_VALUE_TYPE_BOOLDATA:
|
|
_TAI_META_CMP(result, booldata)
|
|
case TAI_ATTR_VALUE_TYPE_CHARDATA:
|
|
*result = !memcmp(lhs->value.chardata, rhs->value.chardata, 32);
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_U8:
|
|
_TAI_META_CMP(result, u8)
|
|
case TAI_ATTR_VALUE_TYPE_S8:
|
|
_TAI_META_CMP(result, s8)
|
|
case TAI_ATTR_VALUE_TYPE_U16:
|
|
_TAI_META_CMP(result, u16)
|
|
case TAI_ATTR_VALUE_TYPE_S16:
|
|
_TAI_META_CMP(result, s16)
|
|
case TAI_ATTR_VALUE_TYPE_U32:
|
|
_TAI_META_CMP(result, u32)
|
|
case TAI_ATTR_VALUE_TYPE_S32:
|
|
_TAI_META_CMP(result, s32)
|
|
case TAI_ATTR_VALUE_TYPE_U64:
|
|
_TAI_META_CMP(result, u64)
|
|
case TAI_ATTR_VALUE_TYPE_S64:
|
|
_TAI_META_CMP(result, s64)
|
|
case TAI_ATTR_VALUE_TYPE_FLT:
|
|
_TAI_META_CMP(result, flt)
|
|
case TAI_ATTR_VALUE_TYPE_PTR:
|
|
_TAI_META_CMP(result, ptr)
|
|
case TAI_ATTR_VALUE_TYPE_OID:
|
|
_TAI_META_CMP(result, oid)
|
|
case TAI_ATTR_VALUE_TYPE_U32RANGE:
|
|
*result = !memcmp(&lhs->value, &rhs->value, sizeof(tai_u32_range_t));
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_S32RANGE:
|
|
*result = !memcmp(&lhs->value, &rhs->value, sizeof(tai_s32_range_t));
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
|
|
*result = !memcmp(&lhs->value, &rhs->value, sizeof(tai_notification_handler_t));
|
|
break;
|
|
case TAI_ATTR_VALUE_TYPE_OBJLIST:
|
|
_TAI_META_CMP_LIST(result, objlist)
|
|
case TAI_ATTR_VALUE_TYPE_CHARLIST:
|
|
_TAI_META_CMP_LIST(result, charlist)
|
|
case TAI_ATTR_VALUE_TYPE_U8LIST:
|
|
_TAI_META_CMP_LIST(result, u8list)
|
|
case TAI_ATTR_VALUE_TYPE_S8LIST:
|
|
_TAI_META_CMP_LIST(result, s8list)
|
|
case TAI_ATTR_VALUE_TYPE_U16LIST:
|
|
_TAI_META_CMP_LIST(result, u16list)
|
|
case TAI_ATTR_VALUE_TYPE_S16LIST:
|
|
_TAI_META_CMP_LIST(result, s16list)
|
|
case TAI_ATTR_VALUE_TYPE_U32LIST:
|
|
_TAI_META_CMP_LIST(result, u32list)
|
|
case TAI_ATTR_VALUE_TYPE_S32LIST:
|
|
_TAI_META_CMP_LIST(result, s32list)
|
|
case TAI_ATTR_VALUE_TYPE_U64LIST:
|
|
_TAI_META_CMP_LIST(result, u64list)
|
|
case TAI_ATTR_VALUE_TYPE_S64LIST:
|
|
_TAI_META_CMP_LIST(result, s64list)
|
|
case TAI_ATTR_VALUE_TYPE_FLOATLIST:
|
|
_TAI_META_CMP_LIST(result, floatlist)
|
|
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
|
|
{
|
|
if( lhs->value.objmaplist.count != rhs->value.objmaplist.count ) {
|
|
*result = false;
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
for ( int i = 0; i < lhs->value.objmaplist.count; i++ ) {
|
|
if ( lhs->value.objmaplist.list[i].key != rhs->value.objmaplist.list[i].key ) {
|
|
*result = false;
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
if ( lhs->value.objmaplist.list[i].value.count != rhs->value.objmaplist.list[i].value.count ) {
|
|
*result = false;
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
for ( int j = 0; j < lhs->value.objmaplist.list[i].value.count; j++ ) {
|
|
if ( lhs->value.objmaplist.list[i].value.list[j] != rhs->value.objmaplist.list[i].value.list[j] ) {
|
|
*result = false;
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
*result = true;
|
|
}
|
|
break;
|
|
default:
|
|
TAI_META_LOG_ERROR("unsupported value type: %d", metadata->attrvaluetype);
|
|
return TAI_STATUS_NOT_SUPPORTED;
|
|
}
|
|
return TAI_STATUS_SUCCESS;
|
|
}
|