#include "MsgHandler.h" void fatal(const char *msg) { ::printf("%s",msg); ::printf("\n"); exit(1); } char *xstrdup(const char *string) { char *ret = strdup(string); if (ret == NULL) { perror("strdup"); fatal("strdup failed"); } return ret; } char *xcalloc(uint8_t count, uint32_t len) { char *ret = (char*)calloc(count, len); if (ret == nullptr) { perror("calloc"); fatal("calloc failed"); } return ret; } void MsgHandler::add_field_type(char type, size_t size) { size_for_type_table[(type > 'A' ? (type-'A') : (type-'a'))] = size; } uint8_t MsgHandler::size_for_type(char type) { uint8_t ret = size_for_type_table[(uint8_t)(type > 'A' ? (type-'A') : (type-'a'))]; if (ret == 0) { ::fprintf(stderr, "Unknown type (%c)\n", type); abort(); } return ret; } void MsgHandler::init_field_types() { add_field_type('b', sizeof(int8_t)); add_field_type('c', sizeof(int16_t)); add_field_type('d', sizeof(double)); add_field_type('e', sizeof(int32_t)); add_field_type('f', sizeof(float)); add_field_type('h', sizeof(int16_t)); add_field_type('i', sizeof(int32_t)); add_field_type('n', sizeof(char[4])); add_field_type('B', sizeof(uint8_t)); add_field_type('C', sizeof(uint16_t)); add_field_type('E', sizeof(uint32_t)); add_field_type('H', sizeof(uint16_t)); add_field_type('I', sizeof(uint32_t)); add_field_type('L', sizeof(int32_t)); add_field_type('M', sizeof(uint8_t)); add_field_type('N', sizeof(char[16])); add_field_type('Z', sizeof(char[64])); add_field_type('q', sizeof(int64_t)); add_field_type('Q', sizeof(uint64_t)); } struct MsgHandler::format_field_info *MsgHandler::find_field_info(const char *label) { for(uint8_t i=0; i strlen(format)) { free(labels); printf("too few field times for labels %s (format=%s) (labels=%s)\n", f.name, format, labels); exit(1); } uint8_t field_type = format[label_offset]; uint8_t length = size_for_type(field_type); add_field(next_label, field_type, msg_offset, length); arg = NULL; msg_offset += length; label_offset++; } if (label_offset != strlen(format)) { printf("too few labels for format (format=%s) (labels=%s)\n", format, labels); } free(labels); free(format); } bool MsgHandler::field_value(uint8_t *msg, const char *label, char *ret, uint8_t retlen) { struct format_field_info *info = find_field_info(label); if (info == NULL) { ::printf("No info for (%s)\n",label); exit(1); } uint8_t offset = info->offset; if (offset == 0) { return false; } memset(ret, '\0', retlen); memcpy(ret, &msg[offset], (retlen < info->length) ? retlen : info->length); return true; } bool MsgHandler::field_value(uint8_t *msg, const char *label, Vector3f &ret) { const char *axes = "XYZ"; uint8_t i; for(i=0; i remaining) { // null termination break; } if (pos != buffer) { *pos++ = ','; } memcpy(pos, field_info[k].label, label_length); pos += label_length; } } } MsgHandler::~MsgHandler() { for (uint8_t k=0; k