diff options
Diffstat (limited to 'analyzer/parser/structs.c')
| -rw-r--r-- | analyzer/parser/structs.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/analyzer/parser/structs.c b/analyzer/parser/structs.c new file mode 100644 index 0000000..dedf0d1 --- /dev/null +++ b/analyzer/parser/structs.c @@ -0,0 +1,51 @@ +#include "parser/structs.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "utils/memory.h" + +void fill_struct(void *obj, const StructField *fields, size_t n_fields, const char *data, size_t data_len, const char *sep) { + for (size_t i = 0; i < n_fields; i++) { + char *next_sep = memmem(data, data_len, sep, strlen(sep)); + size_t len = next_sep ? next_sep - data : data_len; + + char *str = safe_malloc(len + 1); + memcpy(str, data, len); + str[len] = '\0'; + + // parse depending on variable type + void *p_field = (char *)obj + fields[i].offset; + switch (fields[i].type) { + case INT: + sscanf(str, "%d", (int *)p_field); + free(str); + break; + case FLOAT: + sscanf(str, "%f", (float *)p_field); + free(str); + break; + case DOUBLE: + sscanf(str, "%lf", (double *)p_field); + free(str); + break; + case STRING: + *(char **)p_field = str; + break; + } + + // update data pointer and length + if (next_sep) { + data_len -= next_sep - data + strlen(sep); + data = next_sep + strlen(sep); + } + } +} + +void cleanup_struct(void *obj, const StructField *fields, size_t n_fields) { + for (size_t i = 0; i < n_fields; i++) { + if (fields[i].type == STRING) + free(*(char **)((char *)obj + fields[i].offset)); + } +} |
