diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-10-08 20:04:37 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-10-08 20:04:37 +0200 |
commit | 21812f8d763fac8ee9bb3fdc593642b06f405a2b (patch) | |
tree | a55e99115e8c238e6b34159e063ac7d01ba65d54 /pcilib/value.c | |
parent | e28e74adf3d58deb95ce84c66423f347cbe2f859 (diff) | |
download | pcitool-21812f8d763fac8ee9bb3fdc593642b06f405a2b.tar.gz pcitool-21812f8d763fac8ee9bb3fdc593642b06f405a2b.tar.bz2 pcitool-21812f8d763fac8ee9bb3fdc593642b06f405a2b.tar.xz pcitool-21812f8d763fac8ee9bb3fdc593642b06f405a2b.zip |
Base functions for views
Diffstat (limited to 'pcilib/value.c')
-rw-r--r-- | pcilib/value.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/pcilib/value.c b/pcilib/value.c new file mode 100644 index 0000000..cbf347b --- /dev/null +++ b/pcilib/value.c @@ -0,0 +1,168 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + + +#include "pcilib.h" +#include "value.h" +#include "error.h" +#include "unit.h" + +void pcilib_clean_value(pcilib_t *ctx, pcilib_value_t *val) { + if (!val) return; + + if (val->data) { + free(val->data); + val->data = NULL; + } + + memset(val, 0, sizeof(pcilib_value_t)); +} + +int pcilib_copy_value(pcilib_t *ctx, pcilib_value_t *dst, const pcilib_value_t *src) { + if (dst->type != PCILIB_TYPE_INVALID) + pcilib_clean_value(ctx, dst); + + memcpy(dst, src, sizeof(pcilib_value_t)); + + if ((src->size)&&(src->data)) { + dst->data = malloc(src->size); + if (!dst->data) { + dst->type = PCILIB_TYPE_INVALID; + return PCILIB_ERROR_MEMORY; + } + + memcpy(dst->data, src->data, src->size); + } + + return 0; +} + +int pcilib_set_value_from_float(pcilib_t *ctx, pcilib_value_t *value, double fval) { + pcilib_clean_value(ctx, value); + + value->type = PCILIB_TYPE_DOUBLE; + value->fval = fval; + + return 0; +} + +int pcilib_set_value_from_int(pcilib_t *ctx, pcilib_value_t *value, long ival) { + pcilib_clean_value(ctx, value); + + value->type = PCILIB_TYPE_LONG; + value->ival = ival; + + return 0; +} + +/* +double pcilib_value_get_float(pcilib_value_t *val) { + pcilib_value_t copy; + + if (val->type == PCILIB_TYPE_DOUBLE) + return val->fval; + + err = pcilib_copy_value(©, val); + if (err) ??? +} + + +long pcilib_value_get_int(pcilib_value_t *val) { +} +*/ + +int pcilib_convert_value_unit(pcilib_t *ctx, pcilib_value_t *val, const char *unit_name) { + if (val->type == PCILIB_TYPE_INVALID) { + pcilib_error("Can't convert uninitialized value"); + return PCILIB_ERROR_NOTINITIALIZED; + } + + if ((val->type != PCILIB_TYPE_DOUBLE)&&(val->type != PCILIB_TYPE_LONG)) { + pcilib_error("Can't convert value of type %u, only values with integer and float types can be converted to different units", val->type); + return PCILIB_ERROR_INVALID_ARGUMENT; + } + + if (!val->unit) { + pcilib_error("Can't convert value with the unspecified unit"); + return PCILIB_ERROR_INVALID_ARGUMENT; + } + + pcilib_unit_t unit = pcilib_find_unit_by_name(ctx, val->unit); + if (unit == PCILIB_UNIT_INVALID) { + pcilib_error("Can't convert unrecognized unit %s", val->unit); + return PCILIB_ERROR_NOTFOUND; + } + + return pcilib_transform_unit_by_name(ctx, unit_name, val); +} + +int pcilib_convert_value_type(pcilib_t *ctx, pcilib_value_t *val, pcilib_value_type_t type) { + if (val->type == PCILIB_TYPE_INVALID) { + pcilib_error("Can't convert uninitialized value"); + return PCILIB_ERROR_NOTINITIALIZED; + } + + switch (type) { + case PCILIB_TYPE_STRING: + switch (val->type) { + case PCILIB_TYPE_STRING: + break; + case PCILIB_TYPE_DOUBLE: + sprintf(val->str, (val->format?val->format:"%lf"), val->fval); + val->format = NULL; + break; + case PCILIB_TYPE_LONG: + sprintf(val->str, (val->format?val->format:"%li"), val->ival); + val->format = NULL; + break; + default: + return PCILIB_ERROR_NOTSUPPORTED; + } + val->sval = val->str; + break; + case PCILIB_TYPE_DOUBLE: + switch (val->type) { + case PCILIB_TYPE_STRING: + if (sscanf(val->sval, "%lf", &val->fval) != 1) { + pcilib_warning("Can't convert string (%s) to float", val->sval); + return PCILIB_ERROR_INVALID_DATA; + } + val->format = NULL; + break; + case PCILIB_TYPE_DOUBLE: + break; + case PCILIB_TYPE_LONG: + val->fval = val->ival; + val->format = NULL; + break; + default: + return PCILIB_ERROR_NOTSUPPORTED; + } + break; + case PCILIB_TYPE_LONG: + switch (val->type) { + case PCILIB_TYPE_STRING: + if (sscanf(val->sval, "%li", &val->ival) != 1) { + pcilib_warning("Can't convert string (%s) to int", val->sval); + return PCILIB_ERROR_INVALID_DATA; + } + val->format = NULL; + break; + case PCILIB_TYPE_DOUBLE: + val->ival = round(val->fval); + val->format = NULL; + break; + case PCILIB_TYPE_LONG: + break; + default: + return PCILIB_ERROR_NOTSUPPORTED; + } + break; + default: + return PCILIB_ERROR_NOTSUPPORTED; + } + + return 0; +} |