1 /* This file is part of the YAZ toolkit. 2 * Copyright (C) Index Data. 3 * All rights reserved. 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of Index Data nor the names of its contributors 13 * may be used to endorse or promote products derived from this 14 * software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /** 29 * \file marcdisp.h 30 * \brief MARC conversion 31 */ 32 33 #ifndef MARCDISP_H 34 #define MARCDISP_H 35 36 #include <yaz/yconfig.h> 37 #include <stdio.h> 38 #include <yaz/wrbuf.h> 39 40 #include <yaz/nmem.h> 41 #include <yaz/xmltypes.h> 42 #include <yaz/z-opac.h> 43 44 YAZ_BEGIN_CDECL 45 46 /** \brief a yaz_marc_t handle (private content) */ 47 typedef struct yaz_marc_t_ *yaz_marc_t; 48 49 /** \brief construct yaz_marc_t handle */ 50 YAZ_EXPORT yaz_marc_t yaz_marc_create(void); 51 52 /** \brief destroy yaz_marc_t handle */ 53 YAZ_EXPORT void yaz_marc_destroy(yaz_marc_t mt); 54 55 /** \brief set XML mode YAZ_MARC_LINE, YAZ_MARCXML, YAZ_MARC_ISO2709 .. 56 \param mt MARC handle 57 \param xmlmode mode. 58 59 This function ONLY affects yaz_marc_write_mode, yaz_marc_write_trailer. 60 */ 61 YAZ_EXPORT void yaz_marc_xml(yaz_marc_t mt, int xmlmode); 62 63 /** \brief Output format: Line-format */ 64 #define YAZ_MARC_LINE 0 65 /** \brief Output format: simplexml (no longer supported) */ 66 #define YAZ_MARC_SIMPLEXML 1 67 /** \brief Output format: OAI-MARC (no longer supported) */ 68 #define YAZ_MARC_OAIMARC 2 69 /** \brief Output format: MARCXML */ 70 #define YAZ_MARC_MARCXML 3 71 /** \brief Output format: ISO2709 */ 72 #define YAZ_MARC_ISO2709 4 73 /** \brief Output format: MarcXchange (ISO25577) */ 74 #define YAZ_MARC_XCHANGE 5 75 /** \brief Output format: check only (no marc output) */ 76 #define YAZ_MARC_CHECK 6 77 /** \brief Output format: Turbo MARC Index Data format (XML based) */ 78 #define YAZ_MARC_TURBOMARC 7 79 /** \brief Output format: JSON */ 80 #define YAZ_MARC_JSON 8 81 82 /** \brief set iconv handle for character set conversion */ 83 YAZ_EXPORT void yaz_marc_iconv(yaz_marc_t mt, yaz_iconv_t cd); 84 85 /** \brief supply iconv handle for character set conversion */ 86 YAZ_EXPORT yaz_iconv_t yaz_marc_get_iconv(yaz_marc_t mt); 87 88 /** \brief set debug level 89 \param mt handle 90 \param level level, where 0=lowest, 1 more debug, 2 even more 91 */ 92 YAZ_EXPORT void yaz_marc_debug(yaz_marc_t mt, int level); 93 94 /** \brief decodes ISO2709 buffer using straight buffers 95 \param mt marc handle 96 \param buf input buffer 97 \param bsize size of buffer or (-1 if "any size") 98 \param result result to be stored here 99 \param rsize size of result (memory "owned" by yaz_marc_mt handle) 100 101 Decodes MARC in buf of size bsize. 102 On success, result in *result with size *rsize. 103 Returns -1 on error, or size of input record (>0) if OK 104 */ 105 YAZ_EXPORT int yaz_marc_decode_buf(yaz_marc_t mt, const char *buf, int bsize, 106 const char **result, size_t *rsize); 107 108 /** \brief decodes ISO2709/MARC buffer and stores result in WRBUF 109 \param mt handle 110 \param buf input buffer 111 \param bsize size of buffer (-1 if "any size") 112 \param wrbuf WRBUF for output 113 114 Decodes MARC in buf of size bsize. 115 On success, result in wrbuf 116 Returns -1 on error, or size of input record (>0) if OK 117 */ 118 YAZ_EXPORT int yaz_marc_decode_wrbuf(yaz_marc_t mt, const char *buf, 119 int bsize, WRBUF wrbuf); 120 121 YAZ_EXPORT void yaz_marc_subfield_str(yaz_marc_t mt, const char *s); 122 YAZ_EXPORT void yaz_marc_endline_str(yaz_marc_t mt, const char *s); 123 124 /** \brief modifies part of the MARC leader */ 125 YAZ_EXPORT void yaz_marc_modify_leader(yaz_marc_t mt, size_t off, 126 const char *str); 127 128 /** \brief like atoi(3) except that it reads exactly len characters 129 \param buf buffer to read 130 \param len number of bytes to consider (being digits) 131 \returns value 132 */ 133 YAZ_EXPORT int atoi_n(const char *buf, int len); 134 135 /** \brief like atoi_n but checks for proper formatting 136 \param buf buffer to read values from 137 \param size size of buffer 138 \param val value of decimal number (if successful) 139 \retval 0 no value found (non-digits found) 140 \retval 1 value found and *val holds value 141 */ 142 YAZ_EXPORT 143 int atoi_n_check(const char *buf, int size, int *val); 144 145 /** \brief MARC control char: record separator (29 Dec, 1D Hex) */ 146 #define ISO2709_RS 035 147 /** \brief MARC control char: field separator (30 Dec, 1E Hex) */ 148 #define ISO2709_FS 036 149 /** \brief MARC control char: identifier-field separator (31 Dec, 1F Hex) */ 150 #define ISO2709_IDFS 037 151 152 /** \brief read ISO2709/MARC record from buffer 153 \param mt handle 154 \param buf ISO2709 buffer of size bsize 155 \param bsize size of buffer (-1 for unlimited size) 156 157 Parses ISO2709 record from supplied buffer 158 \retval -1 ERROR 159 \retval >0 OK (length) 160 */ 161 YAZ_EXPORT int yaz_marc_read_iso2709(yaz_marc_t mt, 162 const char *buf, int bsize); 163 164 /** \brief read MARC lineformat from stream 165 \param mt handle 166 \param getbyte get one byte handler 167 \param ungetbyte unget one byte handler 168 \param client_data opaque data for handers 169 \retval -1 ERROR 170 \retval >0 OK (length) 171 172 Parses MARC line record from stream 173 Returns > 0 for OK (same as length), -1=ERROR 174 */ 175 YAZ_EXPORT 176 int yaz_marc_read_line(yaz_marc_t mt, 177 int (*getbyte)(void *client_data), 178 void (*ungetbyte)(int b, void *client_data), 179 void *client_data); 180 181 #if YAZ_HAVE_XML2 182 /** \brief parses MARCXML/MarcXchange/TurboMARC record from xmlNode pointer 183 \param mt handle 184 \param ptr is a pointer to root xml node 185 \retval 0 OK 186 \retval -1 ERROR 187 */ 188 YAZ_EXPORT int yaz_marc_read_xml(yaz_marc_t mt, const xmlNode *ptr); 189 #endif 190 191 /** \brief writes record in line format 192 \param mt handle 193 \param wrbuf WRBUF for output 194 \retval 0 OK 195 \retval -1 ERROR 196 */ 197 YAZ_EXPORT int yaz_marc_write_line(yaz_marc_t mt, WRBUF wrbuf); 198 199 /** \brief writes record in MARCXML format 200 \param mt handle 201 \param wrbuf WRBUF for output 202 \retval 0 OK 203 \retval -1 ERROR 204 205 Sets leader[9]='a' . 206 */ 207 YAZ_EXPORT int yaz_marc_write_marcxml(yaz_marc_t mt, WRBUF wrbuf); 208 209 /** \brief writes record in TurboMARC format 210 \param mt handle 211 \param wrbuf WRBUF for output 212 \retval 0 OK 213 \retval -1 ERROR 214 */ 215 YAZ_EXPORT int yaz_marc_write_turbomarc(yaz_marc_t mt, WRBUF wrbuf); 216 217 /** \brief writes record in MarcXchange XML (ISO25577) 218 \param mt handle 219 \param wrbuf WRBUF for output 220 \param format record format (e.g. "MARC21") 221 \param type record type (e.g. Bibliographic) 222 \retval 0 OK 223 \retval -1 ERROR 224 */ 225 YAZ_EXPORT int yaz_marc_write_marcxchange(yaz_marc_t mt, WRBUF wrbuf, 226 const char *format, 227 const char *type); 228 229 /** \brief writes record in ISO2709 format 230 \param mt handle 231 \param wrbuf WRBUF for output 232 \retval 0 OK 233 \retval -1 ERROR 234 */ 235 YAZ_EXPORT int yaz_marc_write_iso2709(yaz_marc_t mt, WRBUF wrbuf); 236 237 /** \brief writes record in mode - given by yaz_marc_xml mode 238 \param mt handle 239 \param wrbuf WRBUF for output 240 \retval 0 OK 241 \retval -1 ERROR 242 243 This function calls yaz_marc_write_iso2709, yaz_marc_write_marcxml, 244 etc.. depending on mode given by yaz_marc_xml. 245 */ 246 YAZ_EXPORT int yaz_marc_write_mode(yaz_marc_t mt, WRBUF wrbuf); 247 248 #if YAZ_HAVE_XML2 249 /** \brief writes MARC record as libxml2 tree 250 \param mt handle 251 \param root_ptr pointer to record node 252 \param ns namespace of record (such as "http://www.loc.gov/MARC21/slim") 253 \param format MarcXchange format (NULL for none) 254 \param type MarcXchange format (NULL for none) 255 \retval 0 Creation successful and *root_ptr is "record" node 256 \retval -1 ERROR 257 */ 258 YAZ_EXPORT 259 int yaz_marc_write_xml(yaz_marc_t mt, xmlNode **root_ptr, 260 const char *ns, 261 const char *format, 262 const char *type); 263 #endif 264 265 /** \brief writes MARC record in JSON represenation 266 \param mt handle 267 \param w WRBUF for output 268 \retval 0 Creation successful 269 \retval -1 ERROR 270 */ 271 YAZ_EXPORT 272 int yaz_marc_write_json(yaz_marc_t mt, WRBUF w); 273 274 /** \brief sets leader spec (for modifying bytes in 24 byte leader) 275 \param mt handle 276 \param leader_spec 277 \retval 0 OK 278 \retval -1 ERROR 279 280 Spec takes form pos=val,pos=val,... 281 where value is either a number (decimal char value) or a 282 string in 'a', e.g. 9='a' 283 284 */ 285 YAZ_EXPORT int yaz_marc_leader_spec(yaz_marc_t mt, const char *leader_spec); 286 287 288 /** \brief sets leader, validates it, and returns important values 289 \param mt handle 290 \param leader of the 24 byte leader to be set 291 \param indicator_length indicator length (returned value) 292 \param identifier_length identifier length (returned value) 293 \param base_address base address (returned value) 294 \param length_data_entry length of data entry (returned value) 295 \param length_starting length of starting 296 \param length_implementation length of implementation defined data 297 */ 298 YAZ_EXPORT 299 void yaz_marc_set_leader(yaz_marc_t mt, const char *leader, 300 int *indicator_length, 301 int *identifier_length, 302 int *base_address, 303 int *length_data_entry, 304 int *length_starting, 305 int *length_implementation); 306 307 308 /** \brief adds MARC comment string 309 \param mt handle 310 \param comment comment to be added) 311 */ 312 YAZ_EXPORT 313 void yaz_marc_add_comment(yaz_marc_t mt, char *comment); 314 315 /** \brief adds MARC annotation - printf interface 316 \param mt handle 317 \param fmt printf format string 318 */ 319 YAZ_EXPORT 320 void yaz_marc_cprintf(yaz_marc_t mt, const char *fmt, ...); 321 322 /** \brief adds subfield to MARC structure 323 \param mt handle 324 \param code_data code data buffer 325 \param code_data_len length of code data 326 */ 327 YAZ_EXPORT 328 void yaz_marc_add_subfield(yaz_marc_t mt, 329 const char *code_data, size_t code_data_len); 330 331 332 /** \brief adds controlfield to MARC structure 333 \param mt handle 334 \param tag (e.g. "001" 335 \param data value for this tag 336 \param data_len length of data 337 */ 338 YAZ_EXPORT 339 void yaz_marc_add_controlfield(yaz_marc_t mt, const char *tag, 340 const char *data, size_t data_len); 341 342 343 #if YAZ_HAVE_XML2 344 /** \brief adds controlfield to MARC structure using xml Nodes 345 \param mt handle 346 \param ptr_tag value of tag (TEXT xmlNode) 347 \param ptr_data value of data (TEXT xmlNode) 348 */ 349 YAZ_EXPORT 350 void yaz_marc_add_controlfield_xml(yaz_marc_t mt, const xmlNode *ptr_tag, 351 const xmlNode *ptr_data); 352 353 /** \brief adds controlfield to MARC structure using xml Nodes for data 354 \param mt handle 355 \param tag string tag 356 \param ptr_data value of data (TEXT xmlNode) 357 */ 358 YAZ_EXPORT 359 void yaz_marc_add_controlfield_xml2(yaz_marc_t mt, char *tag, 360 const xmlNode *ptr_data); 361 #endif 362 363 /** \brief adds datafield to MARC structure using strings 364 \param mt handle 365 \param tag value of tag as string 366 \param indicator indicator string 367 \param indicator_len length of indicator string 368 */ 369 YAZ_EXPORT 370 void yaz_marc_add_datafield(yaz_marc_t mt, const char *tag, 371 const char *indicator, size_t indicator_len); 372 373 #if YAZ_HAVE_XML2 374 /** \brief adds datafield to MARC structure using xml Nodes 375 \param mt handle 376 \param ptr_tag value of tag (TEXT xmlNode) 377 \param indicator indicator string 378 \param indicator_len length of indicator string 379 */ 380 YAZ_EXPORT 381 void yaz_marc_add_datafield_xml(yaz_marc_t mt, const xmlNode *ptr_tag, 382 const char *indicator, size_t indicator_len); 383 384 /** \brief adds datafield to MARC structure using xml Nodes 385 \param mt handle 386 \param tag_value string value (pointer copied verbatim, not strdupped) 387 \param indicators indicator string ; pointer copied verbatim; not strdupped 388 */ 389 YAZ_EXPORT 390 void yaz_marc_add_datafield_xml2(yaz_marc_t mt, char *tag_value, 391 char *indicators); 392 393 #endif 394 395 /** \brief returns memory for MARC handle 396 \param mt handle 397 \retval NMEM handle for MARC system 398 */ 399 YAZ_EXPORT 400 NMEM yaz_marc_get_nmem(yaz_marc_t mt); 401 402 /** \brief clears memory and MARC record 403 \param mt handle 404 */ 405 YAZ_EXPORT 406 void yaz_marc_reset(yaz_marc_t mt); 407 408 /** \brief gets debug level for MARC system 409 \param mt handle 410 */ 411 YAZ_EXPORT 412 int yaz_marc_get_debug(yaz_marc_t mt); 413 414 /** \brief Converts MARC format type to format type(YAZ_MARC_..) 415 \param arg string 416 \retval -1 unknown format (bad arg) 417 \retval >= 0 OK (one of YAZ_MARC - values) 418 */ 419 YAZ_EXPORT 420 int yaz_marc_decode_formatstr(const char *arg); 421 422 /** \brief Enables or disables writing of MARC XML records using Libxml2 423 \param mt handle 424 \param enable 0=disable, 1=enable 425 */ 426 YAZ_EXPORT 427 void yaz_marc_write_using_libxml2(yaz_marc_t mt, int enable); 428 429 /** \brief Performs "pretty" display of OPAC record to WRBUF using marc_t 430 \param mt handle 431 \param r OPAC record 432 \param wrbuf WRBUF for resulting display string 433 434 This function uses iconv_handle of yaz_marc_t for character set 435 conversion of both OPAC + ISO2709 part. 436 \*/ 437 YAZ_EXPORT void yaz_opac_decode_wrbuf(yaz_marc_t mt, Z_OPACRecord *r, 438 WRBUF wrbuf); 439 440 /** \brief Performs "pretty" display of OPAC record to WRBUF using marc_t 441 \param mt handle 442 \param r OPAC record 443 \param wrbuf WRBUF for resulting display string 444 \param cd iconv handle for OPAC content (not ISO2709 part) 445 446 This function uses iconv handle of yaz_marc_t for character set 447 conversion of ISO2709 part and supplied handle (cd) for OPAC part. 448 \*/ 449 YAZ_EXPORT void yaz_opac_decode_wrbuf2(yaz_marc_t mt, Z_OPACRecord *r, 450 WRBUF wrbuf, yaz_iconv_t cd); 451 452 #if YAZ_HAVE_XML2 453 /** \brief Converts XML to OPAC 454 \param mt marc handle 455 \param buf_in XML buffer 456 \param size_in size of XML buffer 457 \param dst Z39.50 OPAC result - allocated by NMEM on marc handle 458 \param cd iconv handle for the OPAC content (not ISO2709 part) 459 \param nmem memory for OPACRecord (if NULL, mt NMEM memory is used) 460 \param syntax OID for embedded MARC (if NULL, USMARC is used) 461 \retval 1 conversion OK 462 \retval 0 conversion NOT OK 463 \*/ 464 YAZ_EXPORT int yaz_xml_to_opac(yaz_marc_t mt, 465 const char *buf_in, size_t size_in, 466 Z_OPACRecord **dst, yaz_iconv_t cd, 467 NMEM nmem, const Odr_oid *syntax); 468 #endif 469 470 /** \brief flushes records 471 \param mt handle 472 \param wr WRBUF for output 473 \retval 0 OK 474 \retval -1 ERROR 475 */ 476 YAZ_EXPORT int yaz_marc_write_trailer(yaz_marc_t mt, WRBUF wr); 477 478 /** \brief enables record collection output 479 \param mt handle 480 */ 481 YAZ_EXPORT void yaz_marc_enable_collection(yaz_marc_t mt); 482 483 struct json_node; 484 485 YAZ_EXPORT int yaz_marc_read_json_node(yaz_marc_t mt, struct json_node *n); 486 487 /** \brief check if MARC21 is UTF-8 encoded 488 \param charset that is given by user 489 \param marc_buf ISO2709 buf 490 \param sz ISO2709 size 491 \retval 1 is probably UTF-8 492 \retval 0 is not UTF-8 493 */ 494 YAZ_EXPORT 495 int yaz_marc_check_marc21_coding(const char *charset, 496 const char *marc_buf, int sz); 497 498 YAZ_EXPORT 499 int yaz_opac_check_marc21_coding(const char *charset, Z_OPACRecord *r); 500 501 502 size_t yaz_marc_sizeof_char(yaz_marc_t mt, const char *buf); 503 504 YAZ_END_CDECL 505 506 #endif 507 /* 508 * Local variables: 509 * c-basic-offset: 4 510 * c-file-style: "Stroustrup" 511 * indent-tabs-mode: nil 512 * End: 513 * vim: shiftwidth=4 tabstop=8 expandtab 514 */ 515 516