Fix null ptr reference for freeReplyObject YAZ-773
[yaz-moved-to-github.git] / src / opac_to_xml.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file opac_to_xml.c
7  * \brief Implements OPAC to XML conversion
8  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16
17 #include <yaz/proto.h>
18 #include <yaz/marcdisp.h>
19
20 static void opac_element_str(WRBUF wrbuf, yaz_iconv_t cd1, yaz_iconv_t cd2,
21                              int l, const char *elem,
22                              const char *data)
23 {
24     if (data)
25     {
26         size_t pos;
27         while (--l >= 0)
28             wrbuf_puts(wrbuf, " ");
29         wrbuf_puts(wrbuf, "<");
30         wrbuf_puts(wrbuf, elem);
31         wrbuf_puts(wrbuf, ">");
32
33         pos = wrbuf->pos; /* save position */
34         if (wrbuf_iconv_write2(wrbuf, cd1, data, strlen(data), wrbuf_xmlputs_n)
35             && cd2)
36         {
37             wrbuf->pos = pos; /* rewind to pos */
38             wrbuf_iconv_write2(wrbuf, cd2, data, strlen(data), wrbuf_xmlputs_n);
39         }
40         wrbuf_puts(wrbuf, "</");
41         wrbuf_puts(wrbuf, elem);
42         wrbuf_puts(wrbuf, ">\n");
43     }
44 }
45
46 static void opac_element_bool(WRBUF wrbuf, int l, const char *elem, int *data)
47 {
48     if (data)
49     {
50         while (--l >= 0)
51             wrbuf_puts(wrbuf, " ");
52         wrbuf_puts(wrbuf, "<");
53         wrbuf_puts(wrbuf, elem);
54         if (*data)
55             wrbuf_puts(wrbuf, " value=\"1\"");
56         else
57             wrbuf_puts(wrbuf, " value=\"0\"");
58         wrbuf_puts(wrbuf, "/>\n");
59     }
60 }
61
62 void yaz_opac_decode_wrbuf2(yaz_marc_t mt, Z_OPACRecord *r, WRBUF wrbuf,
63                             yaz_iconv_t cd2)
64 {
65     int i;
66     yaz_iconv_t cd1 = yaz_marc_get_iconv(mt);
67
68     wrbuf_puts(wrbuf, "<opacRecord>\n");
69     if (r->bibliographicRecord)
70     {
71         Z_External *ext = r->bibliographicRecord;
72
73         wrbuf_puts(wrbuf, "  <bibliographicRecord>\n");
74         if (ext->which == Z_External_octet)
75             yaz_marc_decode_wrbuf(mt, (const char *) ext->u.octet_aligned->buf,
76                                   ext->u.octet_aligned->len, wrbuf);
77         wrbuf_puts(wrbuf, "  </bibliographicRecord>\n");
78     }
79     wrbuf_puts(wrbuf, "<holdings>\n");
80
81     for (i = 0; i < r->num_holdingsData; i++)
82     {
83         Z_HoldingsRecord *h = r->holdingsData[i];
84         wrbuf_puts(wrbuf, " <holding>\n");
85
86         if (h->which == Z_HoldingsRecord_marcHoldingsRecord)
87         {
88             Z_External *ext = h->u.marcHoldingsRecord;
89
90             wrbuf_puts(wrbuf, "  <marcHoldingsRecord>\n");
91             if (ext->which == Z_External_octet)
92                 yaz_marc_decode_wrbuf(mt, (const char *)
93                                       ext->u.octet_aligned->buf,
94                                       ext->u.octet_aligned->len, wrbuf);
95             wrbuf_puts(wrbuf, "  </marcHoldingsRecord>\n");
96         }
97         else if (h->which == Z_HoldingsRecord_holdingsAndCirc)
98         {
99             int j;
100
101             Z_HoldingsAndCircData *d = h->u.holdingsAndCirc;
102
103             opac_element_str(wrbuf, cd1, cd2, 2, "typeOfRecord",
104                              d->typeOfRecord);
105             opac_element_str(wrbuf, cd1, cd2, 2, "encodingLevel",
106                              d->encodingLevel);
107             opac_element_str(wrbuf, cd1, cd2, 2, "format",
108                              d->format);
109             opac_element_str(wrbuf, cd1, cd2, 2, "receiptAcqStatus",
110                              d->receiptAcqStatus);
111             opac_element_str(wrbuf, cd1, cd2, 2, "generalRetention",
112                              d->generalRetention);
113             opac_element_str(wrbuf, cd1, cd2, 2, "completeness",
114                              d->completeness);
115             opac_element_str(wrbuf, cd1, cd2, 2, "dateOfReport",
116                              d->dateOfReport);
117             opac_element_str(wrbuf, cd1, cd2, 2, "nucCode", d->nucCode);
118             opac_element_str(wrbuf, cd1, cd2, 2, "localLocation",
119                              d->localLocation);
120             opac_element_str(wrbuf, cd1, cd2, 2, "shelvingLocation",
121                              d->shelvingLocation);
122             opac_element_str(wrbuf, cd1, cd2, 2, "callNumber",
123                              d->callNumber);
124             opac_element_str(wrbuf, cd1, cd2, 2, "shelvingData",
125                              d->shelvingData);
126             opac_element_str(wrbuf, cd1, cd2, 2, "copyNumber",
127                              d->copyNumber);
128             opac_element_str(wrbuf, cd1, cd2, 2, "publicNote",
129                              d->publicNote);
130             opac_element_str(wrbuf, cd1, cd2, 2, "reproductionNote",
131                              d->reproductionNote);
132             opac_element_str(wrbuf, cd1, cd2, 2, "termsUseRepro",
133                              d->termsUseRepro);
134             opac_element_str(wrbuf, cd1, cd2, 2, "enumAndChron",
135                              d->enumAndChron);
136             if (d->num_volumes)
137             {
138                 wrbuf_puts (wrbuf, "  <volumes>\n");
139                 for (j = 0; j<d->num_volumes; j++)
140                 {
141                     wrbuf_puts (wrbuf, "   <volume>\n");
142                     opac_element_str(wrbuf, cd1, cd2, 4, "enumeration",
143                                      d->volumes[j]->enumeration);
144                     opac_element_str(wrbuf, cd1, cd2, 4, "chronology",
145                                      d->volumes[j]->chronology);
146                     opac_element_str(wrbuf, cd1, cd2, 4, "enumAndChron",
147                                      d->volumes[j]->enumAndChron);
148                     wrbuf_puts(wrbuf, "   </volume>\n");
149                 }
150                 wrbuf_puts(wrbuf, "  </volumes>\n");
151             }
152             if (d->num_circulationData)
153             {
154                 wrbuf_puts (wrbuf, "  <circulations>\n");
155                 for (j = 0; j<d->num_circulationData; j++)
156                 {
157                     wrbuf_puts(wrbuf,"   <circulation>\n");
158                     opac_element_bool(wrbuf, 4, "availableNow",
159                                       d->circulationData[j]->availableNow);
160                     opac_element_str(wrbuf, cd1, cd2, 4,  "availabilityDate",
161                                      d->circulationData[j]->availablityDate);
162                     opac_element_str(wrbuf, cd1, cd2, 4, "availableThru",
163                                       d->circulationData[j]->availableThru);
164                     opac_element_str(wrbuf, cd1, cd2, 4, "restrictions",
165                                       d->circulationData[j]->restrictions);
166                     opac_element_str(wrbuf, cd1, cd2, 4, "itemId",
167                                       d->circulationData[j]->itemId);
168                     opac_element_bool(wrbuf, 4, "renewable",
169                                       d->circulationData[j]->renewable);
170                     opac_element_bool(wrbuf, 4, "onHold",
171                                       d->circulationData[j]->onHold);
172                     opac_element_str(wrbuf, cd1, cd2, 4, "enumAndChron",
173                                       d->circulationData[j]->enumAndChron);
174                     opac_element_str(wrbuf, cd1, cd2, 4, "midspine",
175                                       d->circulationData[j]->midspine);
176                     opac_element_str(wrbuf, cd1, cd2, 4, "temporaryLocation",
177                                       d->circulationData[j]->temporaryLocation);
178                     wrbuf_puts(wrbuf, "   </circulation>\n");
179                 }
180                 wrbuf_puts(wrbuf, "  </circulations>\n");
181             }
182         }
183         wrbuf_puts(wrbuf, " </holding>\n");
184     }
185     wrbuf_puts(wrbuf, "</holdings>\n");
186     wrbuf_puts(wrbuf, "</opacRecord>\n");
187 }
188
189 void yaz_opac_decode_wrbuf(yaz_marc_t mt, Z_OPACRecord *r, WRBUF wrbuf)
190 {
191     yaz_opac_decode_wrbuf2(mt, r, wrbuf, 0);
192 }
193
194 /*
195  * Local variables:
196  * c-basic-offset: 4
197  * c-file-style: "Stroustrup"
198  * indent-tabs-mode: nil
199  * End:
200  * vim: shiftwidth=4 tabstop=8 expandtab
201  */
202