X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fmarc_read_json.c;fp=src%2Fmarc_read_json.c;h=19c570a31045098bbea1cc19f1f483f1b513e534;hb=725b07a551ac42b73d3b621e6a9b696cd13f42d0;hp=0000000000000000000000000000000000000000;hpb=1ecf21b0324959e62628807d5df217d7a761730b;p=yaz-moved-to-github.git diff --git a/src/marc_read_json.c b/src/marc_read_json.c new file mode 100644 index 0000000..19c570a --- /dev/null +++ b/src/marc_read_json.c @@ -0,0 +1,167 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2013 Index Data + * See the file LICENSE for details. + */ + +/** + * \file marc_read_json.c + * \brief Implements reading of MARC in JSON format + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include + +static void parse_subfields(yaz_marc_t mt, struct json_node *sf, WRBUF wtmp) +{ + assert(sf->type == json_node_list); + for (; sf; sf = sf->u.link[1]) + { + if (sf->u.link[0]->type == json_node_object && + sf->u.link[0]->u.link[0]->type == json_node_list) + { + struct json_node *se = sf->u.link[0]->u.link[0]; + for (; se; se = se->u.link[1]) + { + if (se->u.link[0]->type == json_node_pair + && se->u.link[0]->u.link[0]->type == json_node_string + && se->u.link[0]->u.link[1]->type == json_node_string) + { + wrbuf_rewind(wtmp); + wrbuf_puts(wtmp, se->u.link[0]->u.link[0]->u.string); + wrbuf_puts(wtmp, se->u.link[0]->u.link[1]->u.string); + yaz_marc_add_subfield(mt, wrbuf_buf(wtmp), wrbuf_len(wtmp)); + } + } + } + } +} + +static void parse_field(yaz_marc_t mt, struct json_node *p, + int indicator_length, WRBUF wtmp) +{ + if (p->type == json_node_pair && p->u.link[0]->type == json_node_string) + { + struct json_node *l = p->u.link[1]; + if (l->type == json_node_string) + { + yaz_marc_add_controlfield(mt, p->u.link[0]->u.string, + l->u.string, strlen(l->u.string)); + } + else if (l->type == json_node_object && + l->u.link[0]->type == json_node_list) + { + struct json_node *m; + char indicator[10]; + + memset(indicator, ' ', sizeof(indicator)); + for (m = l->u.link[0]; m; m = m->u.link[1]) + { + struct json_node *s = m->u.link[0]; + if (s->type == json_node_pair) + { + if (s->u.link[0]->type == json_node_string + && !strncmp(s->u.link[0]->u.string, "ind", 3) + && s->u.link[1]->type == json_node_string) + { + int ch = s->u.link[0]->u.string[3]; + if (ch >= '1' && ch < '9') + indicator[ch - '1'] = s->u.link[1]->u.string[0]; + } + } + } + yaz_marc_add_datafield(mt, p->u.link[0]->u.string, + indicator, indicator_length); + for (m = l->u.link[0]; m; m = m->u.link[1]) + { + struct json_node *s = m->u.link[0]; + if (s->type == json_node_pair) + { + if (s->u.link[0]->type == json_node_string + && !strcmp(s->u.link[0]->u.string, "subfields") + && s->u.link[1]->type == json_node_array) + { + parse_subfields(mt, s->u.link[1]->u.link[0], wtmp); + } + } + } + } + } +} + +int yaz_marc_read_json_node(yaz_marc_t mt, struct json_node *n) +{ + if (n && n->type == json_node_object) + { + int indicator_length; + int identifier_length; + int base_address; + int length_data_entry; + int length_starting; + int length_implementation; + struct json_node *l; + WRBUF wtmp = wrbuf_alloc(); + for (l = n->u.link[0]; l; l = l->u.link[1]) + { + if (l->u.link[0]->type == json_node_pair && + l->u.link[0]->u.link[0]->type == json_node_string) + { + struct json_node *p = l->u.link[0]; + if (!strcmp(p->u.link[0]->u.string, "leader") && + p->u.link[1]->type == json_node_string && + strlen(p->u.link[1]->u.string) == 24) + { + yaz_marc_set_leader(mt, p->u.link[1]->u.string, + &indicator_length, + &identifier_length, + &base_address, + &length_data_entry, + &length_starting, + &length_implementation); + } + if (!strcmp(p->u.link[0]->u.string, "fields") && + p->u.link[1]->type == json_node_array && + p->u.link[1]->u.link[0] && + p->u.link[1]->u.link[0]->type == json_node_list) + { + struct json_node *l; + for (l = p->u.link[1]->u.link[0]; l; l = l->u.link[1]) + { + if (l->u.link[0]->type == json_node_object) + { + if (l->u.link[0]->u.link[0] && + l->u.link[0]->u.link[0]->type == json_node_list) + { + struct json_node *m = l->u.link[0]->u.link[0]; + for (; m; m = m->u.link[1]) + parse_field(mt, m->u.link[0], + indicator_length, wtmp); + } + } + } + } + } + } + wrbuf_destroy(wtmp); + return 0; + } + return -1; +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +