int yaz_marc_write_json(yaz_marc_t mt, WRBUF w) { int identifier_length; struct yaz_marc_node *n; const char *leader = 0; int first = 1; wrbuf_puts(w, "{\n"); for (n = mt->nodes; n; n = n->next) if (n->which == YAZ_MARC_LEADER) leader = n->u.leader; if (!leader) return -1; if (!atoi_n_check(leader+11, 1, &identifier_length)) return -1; wrbuf_puts(w, "\t\"leader\":\""); wrbuf_json_puts(w, leader); wrbuf_puts(w, "\",\n"); wrbuf_puts(w, "\t\"fields\":\n\t[\n"); for (n = mt->nodes; n; n = n->next) { struct yaz_marc_subfield *s; const char *sep = ""; switch (n->which) { case YAZ_MARC_LEADER: case YAZ_MARC_COMMENT: break; case YAZ_MARC_CONTROLFIELD: if (first) first = 0; else wrbuf_puts(w, ",\n"); wrbuf_puts(w, "\t\t{\n\t\t\t\""); wrbuf_iconv_json_puts(w, mt->iconv_cd, n->u.controlfield.tag); wrbuf_puts(w, "\":\""); wrbuf_iconv_json_puts(w, mt->iconv_cd, n->u.controlfield.data); wrbuf_puts(w, "\"\n\t\t}"); break; case YAZ_MARC_DATAFIELD: if (first) first = 0; else wrbuf_puts(w, ",\n"); wrbuf_puts(w, "\t\t{\n\t\t\t\""); wrbuf_json_puts(w, n->u.datafield.tag); wrbuf_puts(w, "\":\n\t\t\t{\n\t\t\t\t\"subfields\":\n\t\t\t\t[\n"); for (s = n->u.datafield.subfields; s; s = s->next) { size_t using_code_len = get_subfield_len(mt, s->code_data, identifier_length); wrbuf_puts(w, sep); sep = ",\n"; wrbuf_puts(w, "\t\t\t\t\t{\n\t\t\t\t\t\t\""); wrbuf_iconv_json_write(w, mt->iconv_cd, s->code_data, using_code_len); wrbuf_puts(w, "\":\""); wrbuf_iconv_json_puts(w, mt->iconv_cd, s->code_data + using_code_len); wrbuf_puts(w, "\"\n\t\t\t\t\t}"); } wrbuf_puts(w, "\n\t\t\t\t]"); if (n->u.datafield.indicator[0]) { int i; for (i = 0; n->u.datafield.indicator[i]; i++) { wrbuf_printf(w, ",\n\t\t\t\t\"ind%d\":\"%c\"", i + 1, n->u.datafield.indicator[i]); } } wrbuf_puts(w, "\n\t\t\t}\n"); wrbuf_puts(w, "\n\t\t}"); break; } } wrbuf_puts(w, "\n\t]\n"); wrbuf_puts(w, "}\n"); return 0; }
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_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_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_r(node->u.link[0], result, indent); if (node->u.link[1]) { wrbuf_puts(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_r(node->u.link[0], result, indent); wrbuf_puts(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_json_puts(result, node->u.string); wrbuf_puts(result, "\""); break; case json_node_number: wrbuf_printf(result, "%lg", node->u.number); break; case json_node_true: wrbuf_puts(result, "true"); break; case json_node_false: wrbuf_puts(result, "false"); break; case json_node_null: wrbuf_puts(result, "null"); break; } }