/*************************************************************************** * Copyright (C) 04/2008 by Olaf Rempel * * razzor@kopf-tisch.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include "tdc_proto.h" #include "tdc_variable.h" void tdcvar_get_value(struct tdc_var *var, char *buf, int size, int viewmode) { switch ((var->flags & TDC_TYPEMASK) | ((viewmode & 0x01) << 8)) { case TDC_UNSIGNED: switch (var->flags & TDC_SIZEMASK) { case 1: snprintf(buf, size, "%u", var->data_uint8); break; case 2: snprintf(buf, size, "%u", var->data_uint16); break; case 4: snprintf(buf, size, "%u", var->data_uint32); break; case 8: snprintf(buf, size, "%llu", var->data_uint64); break; default: snprintf(buf, size, "???"); break; } break; case TDC_UNSIGNED | 0x100: switch (var->flags & TDC_SIZEMASK) { case 1: snprintf(buf, size, "0x%02x", var->data_uint8); break; case 2: snprintf(buf, size, "0x%04x", var->data_uint16); break; case 4: snprintf(buf, size, "0x%08x", var->data_uint32); break; case 8: snprintf(buf, size, "0x%16llx", var->data_uint64); break; default: snprintf(buf, size, "???"); break; } break; case TDC_SIGNED: switch (var->flags & TDC_SIZEMASK) { case 1: snprintf(buf, size, "%d", (int8_t)var->data_uint8); break; case 2: snprintf(buf, size, "%d", (int16_t)var->data_uint16); break; case 4: snprintf(buf, size, "%d", (int32_t)var->data_uint32); break; case 8: snprintf(buf, size, "%lld", (int64_t)var->data_uint64); break; default: snprintf(buf, size, "???"); break; } break; case TDC_SIGNED | 0x100: switch (var->flags & TDC_SIZEMASK) { case 1: snprintf(buf, size, "0x%02x", (int8_t)var->data_uint8); break; case 2: snprintf(buf, size, "0x%04x", (int16_t)var->data_uint16); break; case 4: snprintf(buf, size, "0x%08x", (int32_t)var->data_uint32); break; case 8: snprintf(buf, size, "0x%16llx", (int64_t)var->data_uint64); break; default: snprintf(buf, size, "???"); break; } break; case TDC_FP: case TDC_FP | 0x100: switch (var->flags & TDC_SIZEMASK) { case sizeof(float): snprintf(buf, size, "%.8f", var->data_float); break; case sizeof(double): snprintf(buf, size, "%.12f", var->data_double); break; default: snprintf(buf, size, "???"); break; } break; case TDC_FIXED: case TDC_FIXED | 0x100: snprintf(buf, size, "???"); break; } } void tdcvar_get_type(struct tdc_var *var, char *buf, int size) { int pos; int width = (var->flags & TDC_SIZEMASK); switch (var->flags & TDC_TYPEMASK) { case TDC_UNSIGNED: pos = snprintf(buf, size, "uint%d_t", width * 8); break; case TDC_SIGNED: pos = snprintf(buf, size, "int%d_t", width * 8); break; case TDC_FP: if (width == sizeof(float)) pos = snprintf(buf, size, "float"); else if (size == sizeof(double)) pos = snprintf(buf, size, "double"); else pos = snprintf(buf, size, "fp%d_t", width * 8); break; case TDC_FIXED: pos = snprintf(buf, size, "fix%d_t", width * 8); break; default: pos = snprintf(buf, size, "???"); break; } if (var->flags & TDC_READONLY) pos = snprintf(buf + pos, size - pos, " (ro)"); } int tdcvar_parse_value(struct tdc_var *var, char *data) { struct tdc_var tmp; int width = (var->flags & TDC_SIZEMASK); switch (var->flags & TDC_TYPEMASK) { case TDC_UNSIGNED: if (strchr(data, '-') != NULL) return -1; errno = 0; if (width < 8) tmp.data_uint32 = strtoul(data, NULL, 0); else tmp.data_uint64 = strtoull(data, NULL, 0); if (errno != 0) { errno = 0; return -1; } break; case TDC_SIGNED: errno = 0; if (width < 8) tmp.data_uint32 = strtol(data, NULL, 0); else tmp.data_uint64 = strtoll(data, NULL, 0); if (errno != 0) { errno = 0; return -1; } break; case TDC_FP: errno = 0; if (width == sizeof(float)) tmp.data_float = strtod(data, NULL); else tmp.data_double = strtod(data, NULL); if (errno != 0) { errno = 0; return -1; } break; case TDC_FIXED: return -1; break; default: break; } memcpy(&var->data, &tmp.data, width); return 0; } double tdcvar_get_double(struct tdc_var *var) { switch (var->flags & TDC_TYPEMASK) { case TDC_UNSIGNED: switch (var->flags & TDC_SIZEMASK) { case 1: return var->data_uint8; case 2: return var->data_uint16; case 4: return var->data_uint32; case 8: return var->data_uint64; } break; case TDC_SIGNED: switch (var->flags & TDC_SIZEMASK) { case 1: return (int8_t)var->data_uint8; case 2: return (int16_t)var->data_uint16; case 4: return (int32_t)var->data_uint32; case 8: return (int64_t)var->data_uint64; } break; case TDC_FP: case TDC_FP | 0x100: switch (var->flags & TDC_SIZEMASK) { case sizeof(float): return var->data_float; case sizeof(double): return var->data_double; } break; } return 0.0; } struct tdc_var * tdcvar_create(int id, uint32_t flags, char *name, int len) { struct tdc_var *var = g_malloc0(sizeof(struct tdc_var) + len + 1); var->id = id & 0xFF; var->flags = flags; strncpy(var->name, name, len); var->name[len] = '\0'; // printf("create_var(%d, 0x%x, '%s', %d)\n", var->id, var->flags, var->name, len); return var; } void tdcvar_update(struct tdc_var *var, uint8_t *data, int len) { if ((var->flags & TDC_SIZEMASK) != len) return; memcpy(&var->data, data, len); } void tdcvar_destroy(struct tdc_var *var) { g_free(var); }