diff options
Diffstat (limited to 'archive/sg_json_writer.c')
-rw-r--r-- | archive/sg_json_writer.c | 360 |
1 files changed, 0 insertions, 360 deletions
diff --git a/archive/sg_json_writer.c b/archive/sg_json_writer.c deleted file mode 100644 index bc1c7b16..00000000 --- a/archive/sg_json_writer.c +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) -/* - * Simple streaming JSON writer - * - * This takes care of the annoying bits of JSON syntax like the commas - * after elements - * - * Authors: Stephen Hemminger <stephen@networkplumber.org> - * - * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc] - */ - -#include <stdio.h> -#include <stdbool.h> -#include <stdarg.h> -#include <assert.h> -#include <malloc.h> -#include <inttypes.h> -#include <stdint.h> - -#include "sg_json_writer.h" - -struct json_writer { - FILE *out; /* output file */ - unsigned depth; /* nesting */ - bool pretty; /* optional whitepace */ - char sep; /* either nul or comma */ -}; - -/* indentation for pretty print */ -static void jsonw_indent(json_writer_t *self) -{ - unsigned i; - for (i = 0; i < self->depth; ++i) - fputs(" ", self->out); -} - -/* end current line and indent if pretty printing */ -static void jsonw_eol(json_writer_t *self) -{ - if (!self->pretty) - return; - - putc('\n', self->out); - jsonw_indent(self); -} - -/* If current object is not empty print a comma */ -static void jsonw_eor(json_writer_t *self) -{ - if (self->sep != '\0') - putc(self->sep, self->out); - self->sep = ','; -} - - -/* Output JSON encoded string */ -/* Handles C escapes, does not do Unicode */ -static void jsonw_puts(json_writer_t *self, const char *str) -{ - putc('"', self->out); - for (; *str; ++str) - switch (*str) { - case '\t': - fputs("\\t", self->out); - break; - case '\n': - fputs("\\n", self->out); - break; - case '\r': - fputs("\\r", self->out); - break; - case '\f': - fputs("\\f", self->out); - break; - case '\b': - fputs("\\b", self->out); - break; - case '\\': - fputs("\\n", self->out); - break; - case '"': - fputs("\\\"", self->out); - break; - case '\'': - fputs("\\\'", self->out); - break; - default: - putc(*str, self->out); - } - putc('"', self->out); -} - -/* Create a new JSON stream */ -json_writer_t *jsonw_new(FILE *f) -{ - json_writer_t *self = malloc(sizeof(*self)); - if (self) { - self->out = f; - self->depth = 0; - self->pretty = false; - self->sep = '\0'; - } - return self; -} - -/* End output to JSON stream */ -void jsonw_destroy(json_writer_t **self_p) -{ - json_writer_t *self = *self_p; - - assert(self->depth == 0); - fputs("\n", self->out); - fflush(self->out); - free(self); - *self_p = NULL; -} - -void jsonw_pretty(json_writer_t *self, bool on) -{ - self->pretty = on; -} - -void jsonw_reset(json_writer_t *self) -{ - assert(self->depth == 0); - self->sep = '\0'; -} - -/* Basic blocks */ -static void jsonw_begin(json_writer_t *self, int c) -{ - jsonw_eor(self); - putc(c, self->out); - ++self->depth; - self->sep = '\0'; -} - -static void jsonw_end(json_writer_t *self, int c) -{ - assert(self->depth > 0); - - --self->depth; - if (self->sep != '\0') - jsonw_eol(self); - putc(c, self->out); - self->sep = ','; -} - - -/* Add a JSON property name */ -void jsonw_name(json_writer_t *self, const char *name) -{ - jsonw_eor(self); - jsonw_eol(self); - self->sep = '\0'; - jsonw_puts(self, name); - putc(':', self->out); - if (self->pretty) - putc(' ', self->out); -} - -void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) -{ - jsonw_eor(self); - putc('"', self->out); - vfprintf(self->out, fmt, ap); - putc('"', self->out); -} - -void jsonw_printf(json_writer_t *self, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - jsonw_eor(self); - vfprintf(self->out, fmt, ap); - va_end(ap); -} - -/* Collections */ -void jsonw_start_object(json_writer_t *self) -{ - jsonw_begin(self, '{'); -} - -void jsonw_end_object(json_writer_t *self) -{ - jsonw_end(self, '}'); -} - -void jsonw_start_array(json_writer_t *self) -{ - jsonw_begin(self, '['); -} - -void jsonw_end_array(json_writer_t *self) -{ - jsonw_end(self, ']'); -} - -/* JSON value types */ -void jsonw_string(json_writer_t *self, const char *value) -{ - jsonw_eor(self); - jsonw_puts(self, value); -} - -void jsonw_bool(json_writer_t *self, bool val) -{ - jsonw_printf(self, "%s", val ? "true" : "false"); -} - -void jsonw_null(json_writer_t *self) -{ - jsonw_printf(self, "null"); -} - -void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num) -{ - jsonw_printf(self, fmt, num); -} - -// #ifdef notused -void jsonw_float(json_writer_t *self, double num) -{ - jsonw_printf(self, "%g", num); -} -// #endif - -void jsonw_hu(json_writer_t *self, unsigned short num) -{ - jsonw_printf(self, "%hu", num); -} - -void jsonw_uint(json_writer_t *self, uint64_t num) -{ - jsonw_printf(self, "%"PRIu64, num); -} - -void jsonw_lluint(json_writer_t *self, unsigned long long int num) -{ - jsonw_printf(self, "%llu", num); -} - -void jsonw_int(json_writer_t *self, int64_t num) -{ - jsonw_printf(self, "%"PRId64, num); -} - -/* Basic name/value objects */ -void jsonw_string_field(json_writer_t *self, const char *prop, const char *val) -{ - jsonw_name(self, prop); - jsonw_string(self, val); -} - -void jsonw_bool_field(json_writer_t *self, const char *prop, bool val) -{ - jsonw_name(self, prop); - jsonw_bool(self, val); -} - -// #ifdef notused -void jsonw_float_field(json_writer_t *self, const char *prop, double val) -{ - jsonw_name(self, prop); - jsonw_float(self, val); -} -// #endif - -void jsonw_float_field_fmt(json_writer_t *self, - const char *prop, - const char *fmt, - double val) -{ - jsonw_name(self, prop); - jsonw_float_fmt(self, fmt, val); -} - -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) -{ - jsonw_name(self, prop); - jsonw_uint(self, num); -} - -void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) -{ - jsonw_name(self, prop); - jsonw_hu(self, num); -} - -void jsonw_lluint_field(json_writer_t *self, - const char *prop, - unsigned long long int num) -{ - jsonw_name(self, prop); - jsonw_lluint(self, num); -} - -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num) -{ - jsonw_name(self, prop); - jsonw_int(self, num); -} - -void jsonw_null_field(json_writer_t *self, const char *prop) -{ - jsonw_name(self, prop); - jsonw_null(self); -} - -#ifdef TEST -int main(int argc, char **argv) -{ - json_writer_t *wr = jsonw_new(stdout); - - jsonw_start_object(wr); - jsonw_pretty(wr, true); - jsonw_name(wr, "Vyatta"); - jsonw_start_object(wr); - jsonw_string_field(wr, "url", "http://vyatta.com"); - jsonw_uint_field(wr, "downloads", 2000000ul); - jsonw_float_field(wr, "stock", 8.16); - - jsonw_name(wr, "ARGV"); - jsonw_start_array(wr); - while (--argc) - jsonw_string(wr, *++argv); - jsonw_end_array(wr); - - jsonw_name(wr, "empty"); - jsonw_start_array(wr); - jsonw_end_array(wr); - - jsonw_name(wr, "NIL"); - jsonw_start_object(wr); - jsonw_end_object(wr); - - jsonw_null_field(wr, "my_null"); - - jsonw_name(wr, "special chars"); - jsonw_start_array(wr); - jsonw_string_field(wr, "slash", "/"); - jsonw_string_field(wr, "newline", "\n"); - jsonw_string_field(wr, "tab", "\t"); - jsonw_string_field(wr, "ff", "\f"); - jsonw_string_field(wr, "quote", "\""); - jsonw_string_field(wr, "tick", "\'"); - jsonw_string_field(wr, "backslash", "\\"); - jsonw_end_array(wr); - - jsonw_end_object(wr); - - jsonw_end_object(wr); - jsonw_destroy(&wr); - return 0; -} - -#endif |