From 5a2a1e0447bc9dc3defe6dca75e6a54312bbb045 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 9 Nov 2014 19:26:48 +0100 Subject: src: consolidate XML/JSON exportation Add new buffer class to consolidate the existing code to export objects in XML/JSON and use it. We save ~700 LOC with this change. The rule and set objects are not yet consolidated. It seems this would require some specific glue code per representation type since lists are arranged differently. This also consolidates the tag names, so we make sure the same are used from XML and JSON by placing them in include/buffer.h. Signed-off-by: Pablo Neira Ayuso --- src/buffer.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/buffer.c (limited to 'src/buffer.c') diff --git a/src/buffer.c b/src/buffer.c new file mode 100644 index 0000000..4fac110 --- /dev/null +++ b/src/buffer.c @@ -0,0 +1,160 @@ +/* + * (C) 2012-2014 by Pablo Neira Ayuso + * + * 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; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include "internal.h" + +int nft_buf_update(struct nft_buf *b, int ret) +{ + if (ret < 0) { + b->fail = true; + } else { + b->off += ret; + if (ret > b->len) + ret = b->len; + b->size += ret; + b->len -= ret; + } + + return ret; +} + +int nft_buf_done(struct nft_buf *b) +{ + if (b->fail) + return -1; + + /* Remove trailing comma in json */ + if (b->size > 0 && b->buf[b->size - 1] == ',') { + b->off--; + b->size--; + b->len++; + } + + return b->off; +} + +static int nft_buf_put(struct nft_buf *b, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(b->buf + b->off, b->len, fmt, ap); + ret = nft_buf_update(b, ret); + va_end(ap); + + return ret; +} + +int nft_buf_open(struct nft_buf *b, int type, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>", tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "{\"%s\":{", tag); + default: + return 0; + } +} + +int nft_buf_close(struct nft_buf *b, int type, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, ""); + case NFT_OUTPUT_JSON: + /* Remove trailing comma in json */ + if (b->size > 0 && b->buf[b->size - 1] == ',') { + b->off--; + b->size--; + b->len++; + } + + return nft_buf_put(b, "}}"); + default: + return 0; + } +} + +int nft_buf_u32(struct nft_buf *b, int type, uint32_t value, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%u", tag, value, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":%u,", tag, value); + default: + return 0; + } +} + +int nft_buf_s32(struct nft_buf *b, int type, uint32_t value, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%d", tag, value, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":%d,", tag, value); + default: + return 0; + } +} + +int nft_buf_u64(struct nft_buf *b, int type, uint64_t value, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%"PRIu64"", tag, value, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":%"PRIu64",", tag, value); + default: + return 0; + } +} + +int nft_buf_str(struct nft_buf *b, int type, const char *str, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%s", tag, str, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":\"%s\",", tag, str); + default: + return 0; + } +} + +int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg, + int reg_type, const char *tag) +{ + int ret; + + switch (type) { + case NFT_OUTPUT_XML: + ret = nft_buf_put(b, "<%s>", tag); + ret = nft_data_reg_snprintf(b->buf + b->off, b->len, reg, + NFT_OUTPUT_XML, 0, reg_type); + nft_buf_update(b, ret); + return nft_buf_put(b, "", tag); + case NFT_OUTPUT_JSON: + nft_buf_put(b, "\"%s\":{", tag); + ret = nft_data_reg_snprintf(b->buf + b->off, b->len, reg, + NFT_OUTPUT_JSON, 0, reg_type); + nft_buf_update(b, ret); + return nft_buf_put(b, "},"); + } + return 0; +} -- cgit v1.2.3