1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2011 Index Data
3 * See the file LICENSE for details.
6 * \file record_render.c
7 * \brief Render Z39.50 records (NamePlusRecord)
17 #include <yaz/marcdisp.h>
18 #include <yaz/record_render.h>
19 #include <yaz/yaz-iconv.h>
20 #include <yaz/proto.h>
21 #include <yaz/oid_db.h>
23 static yaz_iconv_t iconv_create_charset(const char *record_charset)
31 if (record_charset && *record_charset)
33 /* Use "from,to" or just "from" */
34 const char *cp = strchr(record_charset, ',');
35 size_t clen = strlen(record_charset);
38 strncpy( to, cp+1, sizeof(to)-1);
39 to[sizeof(to)-1] = '\0';
40 clen = cp - record_charset;
42 if (clen > sizeof(from)-1)
43 clen = sizeof(from)-1;
46 strncpy(from, record_charset, clen);
50 cd = yaz_iconv_open(to, from);
54 static const char *return_marc_record(WRBUF wrbuf,
57 const char *buf, int sz,
58 const char *record_charset)
60 yaz_iconv_t cd = iconv_create_charset(record_charset);
61 yaz_marc_t mt = yaz_marc_create();
62 const char *ret_string = 0;
65 yaz_marc_iconv(mt, cd);
66 yaz_marc_xml(mt, marc_type);
67 if (yaz_marc_decode_wrbuf(mt, buf, sz, wrbuf) > 0)
70 *len = wrbuf_len(wrbuf);
71 ret_string = wrbuf_cstr(wrbuf);
79 static const char *return_opac_record(WRBUF wrbuf,
82 Z_OPACRecord *opac_rec,
83 const char *record_charset)
85 yaz_iconv_t cd = iconv_create_charset(record_charset);
86 yaz_marc_t mt = yaz_marc_create();
89 yaz_marc_iconv(mt, cd);
90 yaz_marc_xml(mt, marc_type);
92 yaz_opac_decode_wrbuf(mt, opac_rec, wrbuf);
98 *len = wrbuf_len(wrbuf);
99 return wrbuf_cstr(wrbuf);
102 static const char *return_string_record(WRBUF wrbuf,
104 const char *buf, int sz,
105 const char *record_charset)
107 yaz_iconv_t cd = iconv_create_charset(record_charset);
111 wrbuf_iconv_write(wrbuf, cd, buf, sz);
112 wrbuf_iconv_reset(wrbuf, cd);
114 buf = wrbuf_cstr(wrbuf);
115 sz = wrbuf_len(wrbuf);
123 static const char *return_record_wrbuf(WRBUF wrbuf, int *len,
124 Z_NamePlusRecord *npr,
125 int marctype, const char *charset)
127 Z_External *r = (Z_External *) npr->u.databaseRecord;
128 const Odr_oid *oid = r->direct_reference;
131 /* render bibliographic record .. */
132 if (r->which == Z_External_OPAC)
134 return return_opac_record(wrbuf, marctype, len,
137 if (r->which == Z_External_sutrs)
138 return return_string_record(wrbuf, len,
139 (char*) r->u.sutrs->buf,
142 else if (r->which == Z_External_octet)
144 if (yaz_oid_is_iso2709(oid))
146 const char *ret_buf = return_marc_record(
147 wrbuf, marctype, len,
148 (const char *) r->u.octet_aligned->buf,
149 r->u.octet_aligned->len,
153 /* bad ISO2709. Return fail unless raw (ISO2709) is wanted */
154 if (marctype != YAZ_MARC_ISO2709)
157 return return_string_record(wrbuf, len,
158 (const char *) r->u.octet_aligned->buf,
159 r->u.octet_aligned->len,
162 else if (r->which == Z_External_grs1)
164 yaz_display_grs1(wrbuf, r->u.grs1, 0);
165 return return_string_record(wrbuf, len,
173 static const char *get_record_format(WRBUF wrbuf, int *len,
174 Z_NamePlusRecord *npr,
175 int marctype, const char *charset,
178 const char *res = return_record_wrbuf(wrbuf, len, npr, marctype, charset);
180 if (*format == '1' && len)
182 /* try to XML format res */
184 xmlKeepBlanksDefault(0); /* get get xmlDocFormatMemory to work! */
185 doc = xmlParseMemory(res, *len);
190 xmlDocDumpFormatMemory(doc, &xml_mem, &xml_size, 1);
192 wrbuf_write(wrbuf, (const char *) xml_mem, xml_size);
195 res = wrbuf_cstr(wrbuf);
196 *len = wrbuf_len(wrbuf);
203 const char *yaz_record_render(Z_NamePlusRecord *npr, const char *schema,
205 const char *type_spec, int *len)
211 const char *cp = type_spec;
213 for (i = 0; cp[i] && cp[i] != ';' && cp[i] != ' ' && i < sizeof(type)-1;
228 if (!strncmp(cp + i, "charset=", 8))
231 i = i + 8; /* skip charset= */
232 for (j = 0; cp[i] && cp[i] != ';' && cp[i] != ' '; i++)
234 if (j < sizeof(charset)-1)
235 charset[j++] = cp[i];
239 else if (!strncmp(cp + i, "format=", 7))
243 for (j = 0; cp[i] && cp[i] != ';' && cp[i] != ' '; i++)
245 if (j < sizeof(format)-1)
251 if (!strcmp(type, "database"))
254 *len = (npr->databaseName ? strlen(npr->databaseName) : 0);
255 return npr->databaseName;
257 else if (!strcmp(type, "schema"))
260 *len = schema ? strlen(schema) : 0;
263 else if (!strcmp(type, "syntax"))
265 const char *desc = 0;
266 if (npr->which == Z_NamePlusRecord_databaseRecord)
268 Z_External *r = (Z_External *) npr->u.databaseRecord;
269 desc = yaz_oid_to_string(yaz_oid_std(), r->direct_reference, 0);
277 if (npr->which != Z_NamePlusRecord_databaseRecord)
280 /* from now on - we have a database record .. */
281 if (!strcmp(type, "render"))
283 return get_record_format(wrbuf, len, npr, YAZ_MARC_LINE, charset, format);
285 else if (!strcmp(type, "xml"))
287 return get_record_format(wrbuf, len, npr, YAZ_MARC_MARCXML, charset,
290 else if (!strcmp(type, "txml"))
292 return get_record_format(wrbuf, len, npr, YAZ_MARC_TURBOMARC, charset,
295 else if (!strcmp(type, "raw"))
297 return get_record_format(wrbuf, len, npr, YAZ_MARC_ISO2709, charset,
300 else if (!strcmp(type, "ext"))
303 return (const char *) npr->u.databaseRecord;
305 else if (!strcmp(type, "opac"))
307 if (npr->u.databaseRecord->which == Z_External_OPAC)
308 return get_record_format(wrbuf, len, npr, YAZ_MARC_MARCXML, charset,
317 * c-file-style: "Stroustrup"
318 * indent-tabs-mode: nil
320 * vim: shiftwidth=4 tabstop=8 expandtab