value.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include "pcilib.h"
  6. #include "value.h"
  7. #include "error.h"
  8. #include "unit.h"
  9. void pcilib_clean_value(pcilib_t *ctx, pcilib_value_t *val) {
  10. if (!val) return;
  11. if (val->data) {
  12. free(val->data);
  13. val->data = NULL;
  14. }
  15. memset(val, 0, sizeof(pcilib_value_t));
  16. }
  17. int pcilib_copy_value(pcilib_t *ctx, pcilib_value_t *dst, const pcilib_value_t *src) {
  18. if (dst->type != PCILIB_TYPE_INVALID)
  19. pcilib_clean_value(ctx, dst);
  20. memcpy(dst, src, sizeof(pcilib_value_t));
  21. if ((src->size)&&(src->data)) {
  22. dst->data = malloc(src->size);
  23. if (!dst->data) {
  24. dst->type = PCILIB_TYPE_INVALID;
  25. return PCILIB_ERROR_MEMORY;
  26. }
  27. memcpy(dst->data, src->data, src->size);
  28. }
  29. return 0;
  30. }
  31. int pcilib_set_value_from_float(pcilib_t *ctx, pcilib_value_t *value, double fval) {
  32. pcilib_clean_value(ctx, value);
  33. value->type = PCILIB_TYPE_DOUBLE;
  34. value->fval = fval;
  35. return 0;
  36. }
  37. int pcilib_set_value_from_int(pcilib_t *ctx, pcilib_value_t *value, long ival) {
  38. pcilib_clean_value(ctx, value);
  39. value->type = PCILIB_TYPE_LONG;
  40. value->ival = ival;
  41. return 0;
  42. }
  43. /*
  44. double pcilib_value_get_float(pcilib_value_t *val) {
  45. pcilib_value_t copy;
  46. if (val->type == PCILIB_TYPE_DOUBLE)
  47. return val->fval;
  48. err = pcilib_copy_value(&copy, val);
  49. if (err) ???
  50. }
  51. long pcilib_value_get_int(pcilib_value_t *val) {
  52. }
  53. */
  54. int pcilib_convert_value_unit(pcilib_t *ctx, pcilib_value_t *val, const char *unit_name) {
  55. if (val->type == PCILIB_TYPE_INVALID) {
  56. pcilib_error("Can't convert uninitialized value");
  57. return PCILIB_ERROR_NOTINITIALIZED;
  58. }
  59. if ((val->type != PCILIB_TYPE_DOUBLE)&&(val->type != PCILIB_TYPE_LONG)) {
  60. pcilib_error("Can't convert value of type %u, only values with integer and float types can be converted to different units", val->type);
  61. return PCILIB_ERROR_INVALID_ARGUMENT;
  62. }
  63. if (!val->unit) {
  64. pcilib_error("Can't convert value with the unspecified unit");
  65. return PCILIB_ERROR_INVALID_ARGUMENT;
  66. }
  67. pcilib_unit_t unit = pcilib_find_unit_by_name(ctx, val->unit);
  68. if (unit == PCILIB_UNIT_INVALID) {
  69. pcilib_error("Can't convert unrecognized unit %s", val->unit);
  70. return PCILIB_ERROR_NOTFOUND;
  71. }
  72. return pcilib_transform_unit_by_name(ctx, unit_name, val);
  73. }
  74. int pcilib_convert_value_type(pcilib_t *ctx, pcilib_value_t *val, pcilib_value_type_t type) {
  75. if (val->type == PCILIB_TYPE_INVALID) {
  76. pcilib_error("Can't convert uninitialized value");
  77. return PCILIB_ERROR_NOTINITIALIZED;
  78. }
  79. switch (type) {
  80. case PCILIB_TYPE_STRING:
  81. switch (val->type) {
  82. case PCILIB_TYPE_STRING:
  83. break;
  84. case PCILIB_TYPE_DOUBLE:
  85. sprintf(val->str, (val->format?val->format:"%lf"), val->fval);
  86. val->format = NULL;
  87. break;
  88. case PCILIB_TYPE_LONG:
  89. sprintf(val->str, (val->format?val->format:"%li"), val->ival);
  90. val->format = NULL;
  91. break;
  92. default:
  93. return PCILIB_ERROR_NOTSUPPORTED;
  94. }
  95. val->sval = val->str;
  96. break;
  97. case PCILIB_TYPE_DOUBLE:
  98. switch (val->type) {
  99. case PCILIB_TYPE_STRING:
  100. if (sscanf(val->sval, "%lf", &val->fval) != 1) {
  101. pcilib_warning("Can't convert string (%s) to float", val->sval);
  102. return PCILIB_ERROR_INVALID_DATA;
  103. }
  104. val->format = NULL;
  105. break;
  106. case PCILIB_TYPE_DOUBLE:
  107. break;
  108. case PCILIB_TYPE_LONG:
  109. val->fval = val->ival;
  110. val->format = NULL;
  111. break;
  112. default:
  113. return PCILIB_ERROR_NOTSUPPORTED;
  114. }
  115. break;
  116. case PCILIB_TYPE_LONG:
  117. switch (val->type) {
  118. case PCILIB_TYPE_STRING:
  119. if (sscanf(val->sval, "%li", &val->ival) != 1) {
  120. pcilib_warning("Can't convert string (%s) to int", val->sval);
  121. return PCILIB_ERROR_INVALID_DATA;
  122. }
  123. val->format = NULL;
  124. break;
  125. case PCILIB_TYPE_DOUBLE:
  126. val->ival = round(val->fval);
  127. val->format = NULL;
  128. break;
  129. case PCILIB_TYPE_LONG:
  130. break;
  131. default:
  132. return PCILIB_ERROR_NOTSUPPORTED;
  133. }
  134. break;
  135. default:
  136. return PCILIB_ERROR_NOTSUPPORTED;
  137. }
  138. return 0;
  139. }