summaryrefslogtreecommitdiffstats
path: root/pcilib/value.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2015-10-08 20:04:37 +0200
committerSuren A. Chilingaryan <csa@suren.me>2015-10-08 20:04:37 +0200
commit21812f8d763fac8ee9bb3fdc593642b06f405a2b (patch)
treea55e99115e8c238e6b34159e063ac7d01ba65d54 /pcilib/value.c
parente28e74adf3d58deb95ce84c66423f347cbe2f859 (diff)
downloadpcitool-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.c168
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(&copy, 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;
+}