diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/xml/encode.c | 52 | ||||
-rw-r--r-- | src/include/xml/xml.h | 24 |
2 files changed, 76 insertions, 0 deletions
diff --git a/src/include/xml/encode.c b/src/include/xml/encode.c new file mode 100644 index 0000000..b8c090d --- /dev/null +++ b/src/include/xml/encode.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "xml.h" + +static void check(char **str, int *len, int *used, int n); + +char *encode(map_t *map, int len) +{ + int slen = 128, used = 0; + char *str = calloc(slen, sizeof(char)); + + char buf[64]; + for (int i = 0; i < len; ++i) { + check(&str, &slen, &used, snprintf(buf, 64, "<%s", map[i].tag)); + strcat(str, buf); + if (map[i].attrs != NULL) { + for (int j = 0; j < map[i].n_attrs; ++j) { + check(&str, &slen, &used, + snprintf(buf, 64, " %s='%s'", + map[i].attrs[j].tag, (char *)map[i].attrs[j].payload)); + strcat(str, buf); + } + } + check(&str, &slen, &used, 1); + strcat(str, ">"); + if (map[i].size == sizeof(map_t)) { + char *rt = encode((map_t *) map[i].payload, map[i].n); + if (rt == NULL) + return NULL; + check(&str, &slen, &used, strlen(rt)); + strcat(str, rt); + free(rt); + } else if (map[i].size == sizeof(char)) { + check(&str, &slen, &used, map[i].n); + strcat(str, map[i].payload); + } + else + return NULL; + check(&str, &slen, &used, snprintf(buf, 64, "</%s>", map[i].tag)); + strcat(str, buf); + } + return str; +} + +static void check(char **str, int *len, int *used, int n) +{ + if (*used + n >= *len) + *str = realloc(*str, (*len *= 2)); + *used += n; +} diff --git a/src/include/xml/xml.h b/src/include/xml/xml.h new file mode 100644 index 0000000..c20f9d9 --- /dev/null +++ b/src/include/xml/xml.h @@ -0,0 +1,24 @@ +#ifndef XML_H +#define XML_H + +#include <stdio.h> + +struct map { + char *tag; + void *payload; + size_t size; + size_t n; + struct map *attrs; + size_t n_attrs; +}; + +typedef struct map map_t; + +/* decode: decodes the provided xml statement into a map_t */ +map_t *decode(char *xml_str, int *len); + +/* encode: encodes the provided map_t into a xml statement */ +char *encode(map_t *map, int len); + + +#endif |