YAZ  5.34.0
marc_read_json.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 
15 #include <assert.h>
16 #include <stdio.h>
17 #include <string.h>
18 
19 #include <yaz/marcdisp.h>
20 #include <yaz/json.h>
21 #include <yaz/yaz-util.h>
22 
23 static void parse_subfields(yaz_marc_t mt, struct json_node *sf, WRBUF wtmp)
24 {
25  assert(sf->type == json_node_list);
26  for (; sf; sf = sf->u.link[1])
27  {
28  if (sf->u.link[0]->type == json_node_object &&
29  sf->u.link[0]->u.link[0]->type == json_node_list)
30  {
31  struct json_node *se = sf->u.link[0]->u.link[0];
32  for (; se; se = se->u.link[1])
33  {
34  if (se->u.link[0]->type == json_node_pair
35  && se->u.link[0]->u.link[0]->type == json_node_string
36  && se->u.link[0]->u.link[1]->type == json_node_string)
37  {
38  wrbuf_rewind(wtmp);
39  wrbuf_puts(wtmp, se->u.link[0]->u.link[0]->u.string);
40  wrbuf_puts(wtmp, se->u.link[0]->u.link[1]->u.string);
41  yaz_marc_add_subfield(mt, wrbuf_buf(wtmp), wrbuf_len(wtmp));
42  }
43  }
44  }
45  }
46 }
47 
48 static void parse_field(yaz_marc_t mt, struct json_node *p,
49  int indicator_length, WRBUF wtmp)
50 {
51  if (p->type == json_node_pair && p->u.link[0]->type == json_node_string)
52  {
53  struct json_node *l = p->u.link[1];
54  if (l->type == json_node_string)
55  {
57  l->u.string, strlen(l->u.string));
58  }
59  else if (l->type == json_node_object &&
60  l->u.link[0]->type == json_node_list)
61  {
62  struct json_node *m;
63  int j;
64  wrbuf_rewind(wtmp);
65  for (j = 1; j <= indicator_length; j++)
66  {
67  for (m = l->u.link[0]; m; m = m->u.link[1])
68  {
69  struct json_node *s = m->u.link[0];
70  if (s->type == json_node_pair)
71  {
72  if (s->u.link[0]->type == json_node_string
73  && !strncmp(s->u.link[0]->u.string, "ind", 3)
74  && s->u.link[0]->u.string[3] == '0' + j
75  && s->u.link[1]->type == json_node_string)
76  {
77  wrbuf_puts(wtmp, s->u.link[1]->u.string);
78  }
79  }
80  }
81  }
83  wrbuf_cstr(wtmp), wrbuf_len(wtmp));
84  for (m = l->u.link[0]; m; m = m->u.link[1])
85  {
86  struct json_node *s = m->u.link[0];
87  if (s->type == json_node_pair)
88  {
89  if (s->u.link[0]->type == json_node_string
90  && !strcmp(s->u.link[0]->u.string, "subfields")
91  && s->u.link[1]->type == json_node_array)
92  {
93  parse_subfields(mt, s->u.link[1]->u.link[0], wtmp);
94  }
95  }
96  }
97  }
98  }
99 }
100 
102 {
103  if (n && n->type == json_node_object)
104  {
105  int indicator_length;
106  int identifier_length;
107  int base_address;
108  int length_data_entry;
109  int length_starting;
110  int length_implementation;
111  struct json_node *l;
112  WRBUF wtmp = wrbuf_alloc();
113  const char *leader = 0;
114  for (l = n->u.link[0]; l; l = l->u.link[1])
115  {
116  if (l->u.link[0]->type == json_node_pair &&
117  l->u.link[0]->u.link[0]->type == json_node_string)
118  {
119  struct json_node *p = l->u.link[0];
120  if (!strcmp(p->u.link[0]->u.string, "leader") &&
121  p->u.link[1]->type == json_node_string &&
122  strlen(p->u.link[1]->u.string) == 24)
123  {
124  leader = p->u.link[1]->u.string;
125  }
126  }
127  }
128  if (!leader)
129  {
130  yaz_marc_cprintf(mt, "Missing leader. Inserting fake leader");
131  leader = "00000nam a22000000a 4500";
132  }
133  yaz_marc_set_leader(mt, leader,
134  &indicator_length,
135  &identifier_length,
136  &base_address,
137  &length_data_entry,
138  &length_starting,
139  &length_implementation);
140  for (l = n->u.link[0]; l; l = l->u.link[1])
141  {
142  if (l->u.link[0]->type == json_node_pair &&
143  l->u.link[0]->u.link[0]->type == json_node_string)
144  {
145  struct json_node *p = l->u.link[0];
146  if (!strcmp(p->u.link[0]->u.string, "fields") &&
147  p->u.link[1]->type == json_node_array &&
148  p->u.link[1]->u.link[0] &&
149  p->u.link[1]->u.link[0]->type == json_node_list)
150  {
151  struct json_node *l;
152  for (l = p->u.link[1]->u.link[0]; l; l = l->u.link[1])
153  {
154  if (l->u.link[0]->type == json_node_object)
155  {
156  if (l->u.link[0]->u.link[0] &&
157  l->u.link[0]->u.link[0]->type == json_node_list)
158  {
159  struct json_node *m = l->u.link[0]->u.link[0];
160  for (; m; m = m->u.link[1])
161  parse_field(mt, m->u.link[0],
162  indicator_length, wtmp);
163  }
164  }
165  }
166  }
167  }
168  }
169  wrbuf_destroy(wtmp);
170  return 0;
171  }
172  return -1;
173 }
174 
175 /*
176  * Local variables:
177  * c-basic-offset: 4
178  * c-file-style: "Stroustrup"
179  * indent-tabs-mode: nil
180  * End:
181  * vim: shiftwidth=4 tabstop=8 expandtab
182  */
183 
Header for JSON functions.
@ json_node_pair
Definition: json.h:44
@ json_node_array
Definition: json.h:41
@ json_node_list
Definition: json.h:42
@ json_node_string
Definition: json.h:45
@ json_node_object
Definition: json.h:40
static void parse_field(yaz_marc_t mt, struct json_node *p, int indicator_length, WRBUF wtmp)
static void parse_subfields(yaz_marc_t mt, struct json_node *sf, WRBUF wtmp)
int yaz_marc_read_json_node(yaz_marc_t mt, struct json_node *n)
void yaz_marc_cprintf(yaz_marc_t mt, const char *fmt,...)
adds MARC annotation - printf interface
Definition: marcdisp.c:188
void yaz_marc_add_subfield(yaz_marc_t mt, const char *code_data, size_t code_data_len)
adds subfield to MARC structure
Definition: marcdisp.c:316
void yaz_marc_add_datafield(yaz_marc_t mt, const char *tag, const char *indicator, size_t indicator_len)
adds datafield to MARC structure using strings
Definition: marcdisp.c:233
void yaz_marc_set_leader(yaz_marc_t mt, const char *leader_c, int *indicator_length, int *identifier_length, int *base_address, int *length_data_entry, int *length_starting, int *length_implementation)
sets leader, validates it, and returns important values
Definition: marcdisp.c:356
void yaz_marc_add_controlfield(yaz_marc_t mt, const char *tag, const char *data, size_t data_len)
adds controlfield to MARC structure
Definition: marcdisp.c:212
MARC conversion.
JSON node.
Definition: json.h:53
char * string
Definition: json.h:56
union json_node::@25 u
struct json_node * link[2]
Definition: json.h:58
enum json_node_type type
Definition: json.h:54
string buffer
Definition: wrbuf.h:43
the internals of a yaz_marc_t handle
Definition: marcdisp.c:86
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition: wrbuf.c:38
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition: wrbuf.c:47
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition: wrbuf.c:25
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition: wrbuf.c:281
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition: wrbuf.c:89
#define wrbuf_buf(b)
Definition: wrbuf.h:251
#define wrbuf_len(b)
Definition: wrbuf.h:250
Header for common YAZ utilities.