X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fjson.c;h=a214eac190a655d7fc795530406aa54d9dfb9cdb;hp=4c416134d5c4277cfbe85be69cd53624a3eee53f;hb=8ceaeefe2e491935cba91f56007308be6e4996e6;hpb=88d3bedf772316f87e1996f655ccf8d1e2589755 diff --git a/src/json.c b/src/json.c index 4c41613..a214eac 100644 --- a/src/json.c +++ b/src/json.c @@ -1,12 +1,14 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2010 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ - /** * \file json.c * \brief JSON encoding/decoding */ +#if HAVE_CONFIG_H +#include +#endif #include @@ -34,7 +36,7 @@ struct json_parser_s { json_parser_t json_parser_create(void) { json_parser_t p = (json_parser_t) xmalloc(sizeof(*p)); - + p->buf = 0; p->cp = 0; p->err_msg = 0; @@ -134,7 +136,7 @@ static int json_one_char(const char **p, char *out) case 'b': *out = '\b'; break; case 'f': - *out = '\b'; break; + *out = '\f'; break; case 'n': *out = '\n'; break; case 'r': @@ -196,7 +198,7 @@ static struct json_node *json_parse_string(json_parser_t p) } n = json_new_node(p, json_node_string); dst = n->u.string = (char *) xmalloc(l + 1); - + cp = p->cp; while (*cp && *cp != '"') { @@ -300,7 +302,7 @@ static struct json_node *json_parse_elements(json_parser_t p) } m2 = json_new_node(p, json_node_list); m2->u.link[0] = n2; - + m1->u.link[1] = m2; m1 = m2; } @@ -375,7 +377,7 @@ static struct json_node *json_parse_members(json_parser_t p) } m2 = json_new_node(p, json_node_list); m2->u.link[0] = n2; - + m1->u.link[1] = m2; m1 = m2; } @@ -420,7 +422,7 @@ struct json_node *json_parser_parse(json_parser_t p, const char *json_str) p->buf = json_str; p->cp = p->buf; - n = json_parse_object(p); + n = json_parse_value(p); if (!n) return 0; c = look_ch(p); @@ -433,7 +435,8 @@ struct json_node *json_parser_parse(json_parser_t p, const char *json_str) return n; } -struct json_node *json_parse(const char *json_str, const char **errmsg) +struct json_node *json_parse2(const char *json_str, const char **errmsg, + size_t *pos) { json_parser_t p = json_parser_create(); struct json_node *n = 0; @@ -447,43 +450,92 @@ struct json_node *json_parse(const char *json_str, const char **errmsg) n = json_parser_parse(p, json_str); if (!n && errmsg) *errmsg = json_parser_get_errmsg(p); + if (pos) + *pos = json_parser_get_position(p); json_parser_destroy(p); } return n; } -void json_write_wrbuf(struct json_node *node, WRBUF result) +struct json_node *json_parse(const char *json_str, const char **errmsg) +{ + return json_parse2(json_str, errmsg, 0); +} + +static void json_indent(WRBUF result, int indent) +{ + size_t l = wrbuf_len(result); + if (l == 0 || wrbuf_buf(result)[l-1] == '\n') + { + int i; + for (i = 0; i < indent; i++) + wrbuf_putc(result, ' '); + } +} + +static void json_write_wrbuf_r(struct json_node *node, WRBUF result, int indent) { + int sub_indent = -1; + if (indent >= 0) + sub_indent = indent + 1; switch (node->type) { case json_node_object: + json_indent(result, indent); wrbuf_puts(result, "{"); + if (indent >= 0) + { + wrbuf_puts(result, "\n"); + json_indent(result, sub_indent); + } if (node->u.link[0]) - json_write_wrbuf(node->u.link[0], result); + json_write_wrbuf_r(node->u.link[0], result, sub_indent); + if (indent >= 0) + { + wrbuf_puts(result, "\n"); + json_indent(result, indent); + } wrbuf_puts(result, "}"); break; case json_node_array: + json_indent(result, indent); wrbuf_puts(result, "["); + if (indent >= 0) + { + wrbuf_puts(result, "\n"); + json_indent(result, sub_indent); + } if (node->u.link[0]) - json_write_wrbuf(node->u.link[0], result); + { + json_write_wrbuf_r(node->u.link[0], result, sub_indent); + } + if (indent >= 0) + { + wrbuf_puts(result, "\n"); + json_indent(result, indent); + } wrbuf_puts(result, "]"); break; case json_node_list: - json_write_wrbuf(node->u.link[0], result); + json_write_wrbuf_r(node->u.link[0], result, indent); if (node->u.link[1]) { wrbuf_puts(result, ","); - json_write_wrbuf(node->u.link[1], result); + if (indent >= 0) + wrbuf_puts(result, " "); + json_write_wrbuf_r(node->u.link[1], result, indent); } break; case json_node_pair: - json_write_wrbuf(node->u.link[0], result); + json_write_wrbuf_r(node->u.link[0], result, indent); wrbuf_puts(result, ":"); - json_write_wrbuf(node->u.link[1], result); + if (indent >= 0) + wrbuf_puts(result, " "); + json_write_wrbuf_r(node->u.link[1], result, indent); break; case json_node_string: wrbuf_puts(result, "\""); - wrbuf_puts(result, node->u.string); + wrbuf_json_puts(result, node->u.string); wrbuf_puts(result, "\""); break; case json_node_number: @@ -501,6 +553,16 @@ void json_write_wrbuf(struct json_node *node, WRBUF result) } } +void json_write_wrbuf_pretty(struct json_node *node, WRBUF result) +{ + json_write_wrbuf_r(node, result, 1); +} + +void json_write_wrbuf(struct json_node *node, WRBUF result) +{ + json_write_wrbuf_r(node, result, -1); +} + static struct json_node **json_get_objectp(struct json_node *n, const char *name) { @@ -521,7 +583,7 @@ static struct json_node **json_get_objectp(struct json_node *n, struct json_node *json_get_object(struct json_node *n, const char *name) { struct json_node **np = json_get_objectp(n, name); - + if (np) return *np; return 0; @@ -530,7 +592,7 @@ struct json_node *json_get_object(struct json_node *n, const char *name) struct json_node *json_detach_object(struct json_node *n, const char *name) { struct json_node **np = json_get_objectp(n, name); - + if (np) { struct json_node *n = *np; @@ -586,6 +648,11 @@ const char *json_parser_get_errmsg(json_parser_t p) return p->err_msg; } +size_t json_parser_get_position(json_parser_t p) +{ + return p->cp - p->buf; +} + /* * Local variables: * c-basic-offset: 4