30 #include <libxml/parser.h>
31 #include <libxml/tree.h>
161 const xmlNode *ptr_data)
170 const xmlNode *ptr_data)
213 const char *data,
size_t data_len)
224 sprintf(msg,
"controlfield:");
225 for (i = 0; i < 16 && i < data_len; i++)
226 sprintf(msg + strlen(msg),
" %02X", data[i] & 0xff);
228 sprintf(msg + strlen(msg),
" ..");
234 const char *indicator,
size_t indicator_len)
255 const char *attribute_name,
char *code_data,
size_t code_len)
262 for (index = 0; index < code_len; index++)
264 if (!((code_data[index] >=
'0' && code_data[index] <=
'9') ||
265 (code_data[index] >=
'a' && code_data[index] <=
'z') ||
266 (code_data[index] >=
'A' && code_data[index] <=
'Z')))
270 if (encode && attribute_name)
273 if (!encode || attribute_name)
278 if (encode && attribute_name)
285 const char *indicator,
size_t indicator_len)
317 const char *code_data,
size_t code_data_len)
324 sprintf(msg,
"subfield:");
325 for (i = 0; i < 16 && i < code_data_len; i++)
326 sprintf(msg + strlen(msg),
" %02X", code_data[i] & 0xff);
327 if (i < code_data_len)
328 sprintf(msg + strlen(msg),
" ..");
347 if (leader[offset] <
' ' || leader[offset] > 127)
350 "Leader character at offset %d is non-ASCII. "
351 "Setting value to '%c'", offset, ch_default);
352 leader[offset] = ch_default;
357 int *indicator_length,
358 int *identifier_length,
360 int *length_data_entry,
361 int *length_starting,
362 int *length_implementation)
366 memcpy(leader, leader_c, 24);
373 if (!
atoi_n_check(leader+10, 1, indicator_length) || *indicator_length == 0)
376 " hold a number 1-9. Assuming 2");
378 *indicator_length = 2;
380 if (!
atoi_n_check(leader+11, 1, identifier_length) || *identifier_length == 0)
383 " hold a number 1-9. Assuming 2");
385 *identifier_length = 2;
390 " hold a number. Assuming 0");
397 *length_data_entry < 3)
400 " hold a number 3-9. Assuming 4");
401 *length_data_entry = 4;
404 if (!
atoi_n_check(leader+21, 1, length_starting) || *length_starting < 4)
407 " hold a number 4-9. Assuming 5");
408 *length_starting = 5;
414 " hold a number. Assuming 0");
415 *length_implementation = 0;
450 for (i = 1; i<5; i++)
453 size_t outbytesleft =
sizeof(outbuf);
455 const char *inp = buf;
457 size_t inbytesleft = i;
459 &outp, &outbytesleft);
461 if (r != (
size_t) (-1))
472 if (error == 0 && no_read > 0)
494 int identifier_length;
526 int identifier_length)
531 if (identifier_length > 2)
532 return identifier_length - 1;
540 int identifier_length;
669 int identifier_length;
830 xmlDocPtr doc = xmlNewDoc(BAD_CAST
"1.0");
833 xmlDocSetRootElement(doc, root_ptr);
834 xmlDocDumpMemory(doc, &buf_out, &len_out);
857 "http://www.loc.gov/MARC21/slim",
868 "http://www.indexdata.com/turbomarc", 0, 0, 1);
876 "info:lc/xmlns/marcxchange-v1",
882 xmlNode *ptr,
int turbo)
893 if (ilen <
sizeof(ind_val) - 1)
898 ind_val[ilen] =
'\0';
899 xmlNewProp(ptr, BAD_CAST ind_str, BAD_CAST ind_val);
909 xmlNsPtr ns_record,
WRBUF wr_cdata,
910 int identifier_length)
921 ptr = xmlNewChild(record_ptr, ns_record, BAD_CAST field, 0);
927 xmlNode *ptr_subfield;
937 ptr_subfield = xmlNewTextChild(ptr, ns_record,
945 xmlNewProp(ptr_subfield, BAD_CAST
"code", BAD_CAST
wrbuf_cstr(wr_cdata));
957 int identifier_length;
977 record_ptr = xmlNewNode(0, BAD_CAST
"r");
978 *root_ptr = record_ptr;
980 ns_record = xmlNewNs(record_ptr, BAD_CAST ns, 0);
981 xmlSetNs(record_ptr, ns_record);
984 xmlNewProp(record_ptr, BAD_CAST
"format", BAD_CAST format);
986 xmlNewProp(record_ptr, BAD_CAST
"type", BAD_CAST
type);
1006 ptr = xmlNewTextChild(record_ptr, ns_record,
1011 ptr = xmlNewComment(BAD_CAST n->
u.
comment);
1012 xmlAddChild(record_ptr, ptr);
1015 xmlNewTextChild(record_ptr, ns_record, BAD_CAST
"l",
1031 int identifier_length;
1033 xmlNode *record_ptr;
1051 record_ptr = xmlNewNode(0, BAD_CAST
"record");
1052 *root_ptr = record_ptr;
1054 ns_record = xmlNewNs(record_ptr, BAD_CAST ns, 0);
1055 xmlSetNs(record_ptr, ns_record);
1058 xmlNewProp(record_ptr, BAD_CAST
"format", BAD_CAST format);
1060 xmlNewProp(record_ptr, BAD_CAST
"type", BAD_CAST
type);
1069 ptr = xmlNewChild(record_ptr, ns_record, BAD_CAST
"datafield", 0);
1070 xmlNewProp(ptr, BAD_CAST
"tag", BAD_CAST n->
u.
datafield.
tag);
1074 xmlNode *ptr_subfield;
1081 ptr_subfield = xmlNewTextChild(
1083 BAD_CAST
"subfield", BAD_CAST
wrbuf_cstr(wr_cdata));
1088 xmlNewProp(ptr_subfield, BAD_CAST
"code",
1097 ptr = xmlNewTextChild(record_ptr, ns_record,
1098 BAD_CAST
"controlfield",
1104 ptr = xmlNewComment(BAD_CAST n->
u.
comment);
1105 xmlAddChild(record_ptr, ptr);
1108 xmlNewTextChild(record_ptr, ns_record, BAD_CAST
"leader",
1122 int indicator_length;
1123 int identifier_length;
1124 int length_data_entry;
1125 int length_starting;
1126 int length_implementation;
1127 int data_offset = 0;
1129 WRBUF wr_dir, wr_head, wr_data_tmp;
1153 int data_length = 0;
1154 const char *tag = 0;
1190 if (data_length && tag)
1192 if (
wrbuf_len(wr_dir) + 40 + data_offset + data_length > 99999)
1198 wrbuf_printf(wr_dir,
"%0*d", length_data_entry, data_length);
1199 wrbuf_printf(wr_dir,
"%0*d", length_starting, data_offset);
1200 data_offset += data_length;
1212 wrbuf_printf(wr_head,
"%05d", base_address + data_offset + 1);
1226 for (n = mt->
nodes; n != cap_node; n = n->
next)
1259 int identifier_length;
1283 const char *sep =
"";
1363 const char **result,
size_t *rsize)
1405 memcpy(
leader+off, str, strlen(str));
1416 char dummy_leader[24];
1426 const char *cp = leader_spec;
1431 int no_read = 0, no = 0;
1433 no = sscanf(cp,
"%d=%20[^,]%n", &pos, val, &no_read);
1434 if (no < 2 || no_read < 3)
1436 if (pos < 0 || (
size_t) pos >= size)
1441 const char *vp = strchr(val+1,
'\'');
1447 if (len + pos > size)
1449 memcpy(
leader + pos, val+1, len);
1451 else if (*val >=
'0' && *val <=
'9')
1470 if (!strcmp(arg,
"marc"))
1472 if (!strcmp(arg,
"marcxml"))
1474 if (!strcmp(arg,
"turbomarc"))
1476 if (!strcmp(arg,
"marcxchange"))
1478 if (!strcmp(arg,
"line"))
1480 if (!strcmp(arg,
"json"))
1491 const char *marc_buf,
int sz)
1494 !
yaz_matchstr(charset,
"MARC8")) && marc_buf && sz > 25
1495 && marc_buf[9] ==
'a')
int atoi_n_check(const char *buf, int size, int *val)
like atoi_n but checks for proper formatting
int yaz_marc_read_iso2709(yaz_marc_t mt, const char *buf, int bsize)
read ISO2709/MARC record from buffer
int yaz_marc_leader_spec(yaz_marc_t mt, const char *leader_spec)
sets leader spec (for modifying bytes in 24 byte leader)
int yaz_marc_write_iso2709(yaz_marc_t mt, WRBUF wr)
writes record in ISO2709 format
void yaz_marc_add_controlfield_xml(yaz_marc_t mt, const xmlNode *ptr_tag, const xmlNode *ptr_data)
adds controlfield to MARC structure using xml Nodes
static int yaz_marc_write_xml_turbo_xml(yaz_marc_t mt, xmlNode **root_ptr, const char *ns, const char *format, const char *type)
static const char * subfield_name[2]
void yaz_marc_cprintf(yaz_marc_t mt, const char *fmt,...)
adds MARC annotation - printf interface
int yaz_marc_check_marc21_coding(const char *charset, const char *marc_buf, int sz)
check if MARC21 is UTF-8 encoded
yaz_marc_t yaz_marc_create(void)
construct yaz_marc_t handle
int yaz_marc_write_line(yaz_marc_t mt, WRBUF wr)
writes record in line format
static void check_ascii(yaz_marc_t mt, char *leader, int offset, int ch_default)
size_t yaz_marc_sizeof_char(yaz_marc_t mt, const char *buf)
void yaz_marc_iconv(yaz_marc_t mt, yaz_iconv_t cd)
set iconv handle for character set conversion
static const char * controlfield_name[2]
static const char * leader_name[2]
void yaz_marc_add_leader(yaz_marc_t mt, const char *leader, size_t leader_len)
void yaz_marc_xml(yaz_marc_t mt, int xmlmode)
set XML mode YAZ_MARC_LINE, YAZ_MARCXML, YAZ_MARC_ISO2709 ..
void yaz_marc_add_subfield(yaz_marc_t mt, const char *code_data, size_t code_data_len)
adds subfield to MARC structure
void yaz_marc_add_datafield_xml(yaz_marc_t mt, const xmlNode *ptr_tag, const char *indicator, size_t indicator_len)
adds datafield to MARC structure using xml Nodes
void yaz_marc_write_using_libxml2(yaz_marc_t mt, int enable)
Enables or disables writing of MARC XML records using Libxml2.
NMEM yaz_marc_get_nmem(yaz_marc_t mt)
returns memory for MARC handle
void yaz_marc_endline_str(yaz_marc_t mt, const char *s)
int yaz_marc_get_debug(yaz_marc_t mt)
gets debug level for MARC system
static struct yaz_marc_node * yaz_marc_add_node(yaz_marc_t mt)
int yaz_marc_write_turbomarc(yaz_marc_t mt, WRBUF wr)
writes record in TurboMARC format
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
YAZ_MARC_NODE_TYPE
node types for yaz_marc_node
void yaz_marc_add_datafield_xml2(yaz_marc_t mt, char *tag_value, char *indicators)
adds datafield to MARC structure using xml Nodes
void yaz_marc_modify_leader(yaz_marc_t mt, size_t off, const char *str)
modifies part of the MARC leader
int yaz_marc_write_xml(yaz_marc_t mt, xmlNode **root_ptr, const char *ns, const char *format, const char *type)
writes MARC record as libxml2 tree
int yaz_marc_decode_formatstr(const char *arg)
Converts MARC format type to format type(YAZ_MARC_..)
int yaz_marc_write_marcxml(yaz_marc_t mt, WRBUF wr)
writes record in MARCXML format
static void write_xml_indicator(yaz_marc_t mt, struct yaz_marc_node *n, xmlNode *ptr, int turbo)
void yaz_marc_subfield_str(yaz_marc_t mt, const char *s)
yaz_iconv_t yaz_marc_get_iconv(yaz_marc_t mt)
supply iconv handle for character set conversion
void yaz_marc_destroy(yaz_marc_t mt)
destroy yaz_marc_t handle
int yaz_marc_write_check(yaz_marc_t mt, WRBUF wr)
static const char * record_name[2]
static int yaz_marc_write_marcxml_wrbuf(yaz_marc_t mt, WRBUF wr, const char *ns, const char *format, const char *type, int turbo)
common MARC XML/Xchange/turbomarc writer
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
static void marc_iconv_reset(yaz_marc_t mt, WRBUF wr)
static void add_marc_datafield_turbo_xml(yaz_marc_t mt, struct yaz_marc_node *n, xmlNode *record_ptr, xmlNsPtr ns_record, WRBUF wr_cdata, int identifier_length)
void yaz_marc_add_controlfield_xml2(yaz_marc_t mt, char *tag, const xmlNode *ptr_data)
adds controlfield to MARC structure using xml Nodes for data
int yaz_marc_write_mode(yaz_marc_t mt, WRBUF wr)
writes record in mode - given by yaz_marc_xml mode
void yaz_marc_add_controlfield(yaz_marc_t mt, const char *tag, const char *data, size_t data_len)
adds controlfield to MARC structure
void yaz_marc_add_comment(yaz_marc_t mt, char *comment)
adds MARC comment string
static const char * datafield_name[2]
void yaz_marc_reset(yaz_marc_t mt)
clears memory and MARC record
int yaz_marc_write_marcxchange(yaz_marc_t mt, WRBUF wr, const char *format, const char *type)
writes record in MarcXchange XML (ISO25577)
int yaz_marc_write_json(yaz_marc_t mt, WRBUF w)
writes MARC record in JSON represenation
void yaz_marc_enable_collection(yaz_marc_t mt)
enables record collection output
static int marc_exec_leader(const char *leader_spec, char *leader, size_t size)
int yaz_marc_write_trailer(yaz_marc_t mt, WRBUF wr)
flushes records
int yaz_marc_decode_buf(yaz_marc_t mt, const char *buf, int bsize, const char **result, size_t *rsize)
decodes ISO2709 buffer using straight buffers
void yaz_marc_datafield_set_indicators(struct yaz_marc_node *n, char *indicator)
static const char * indicator_name[2]
void yaz_marc_debug(yaz_marc_t mt, int level)
set debug level
static size_t cdata_one_character(yaz_marc_t mt, const char *buf)
int yaz_marc_decode_wrbuf(yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
decodes ISO2709/MARC buffer and stores result in WRBUF
static int element_name_append_attribute_value(yaz_marc_t mt, WRBUF buffer, const char *attribute_name, char *code_data, size_t code_len)
adds a attribute value to the element name if it is plain chars
static int yaz_marc_write_marcxml_ns(yaz_marc_t mt, WRBUF wr, const char *ns, const char *format, const char *type, int turbo)
static size_t get_subfield_len(yaz_marc_t mt, const char *data, int identifier_length)
#define YAZ_MARC_MARCXML
Output format: MARCXML.
#define ISO2709_FS
MARC control char: field separator (30 Dec, 1E Hex)
#define YAZ_MARC_XCHANGE
Output format: MarcXchange (ISO25577)
#define YAZ_MARC_ISO2709
Output format: ISO2709.
#define YAZ_MARC_LINE
Output format: Line-format.
#define YAZ_MARC_CHECK
Output format: check only (no marc output)
#define YAZ_MARC_JSON
Output format: JSON.
#define ISO2709_IDFS
MARC control char: identifier-field separator (31 Dec, 1F Hex)
#define ISO2709_RS
MARC control char: record separator (29 Dec, 1D Hex)
#define YAZ_MARC_TURBOMARC
Output format: Turbo MARC Index Data format (XML based)
struct yaz_marc_t_ * yaz_marc_t
a yaz_marc_t handle (private content)
int yaz_matchstr(const char *s1, const char *s2)
match strings - independent of case and '-'
void nmem_reset(NMEM n)
releases memory associaged with an NMEM handle
NMEM nmem_create(void)
returns new NMEM handle
void * nmem_malloc(NMEM n, size_t size)
allocates memory block on NMEM handle
void nmem_destroy(NMEM n)
destroys NMEM handle and memory associated with it
Header for Nibble Memory functions + Libxml2 specific stuff.
char * nmem_text_node_cdata(const xmlNode *ptr_cdata, NMEM nmem)
copies TEXT Libxml2 node data to NMEM
char * nmem_strdupn(NMEM mem, const char *src, size_t n)
allocates string of certain size on NMEM handle
char * nmem_strdup(NMEM mem, const char *src)
allocates string on NMEM handle (similar strdup)
size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
just like iconv(3)
void yaz_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
Header for config file reading utilities.
represents a control field
struct yaz_marc_subfield * subfields
struct yaz_marc_datafield datafield
struct yaz_marc_controlfield controlfield
enum YAZ_MARC_NODE_TYPE which
struct yaz_marc_node * next
union yaz_marc_node::@5 u
struct yaz_marc_subfield * next
the internals of a yaz_marc_t handle
enum yaz_collection_state enable_collection
struct yaz_marc_subfield ** subfield_pp
struct yaz_marc_node ** nodes_pp
struct yaz_marc_node * nodes
unsigned long yaz_read_UTF8_char(const unsigned char *inp, size_t inbytesleft, size_t *no_read, int *error)
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
void wrbuf_iconv_reset(WRBUF b, yaz_iconv_t cd)
iconv reset(flush) to WRBUF
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
WRBUF wrbuf_alloc(void)
construct WRBUF
void wrbuf_iconv_putchar(WRBUF b, yaz_iconv_t cd, int ch)
iconv converts character and appends to WRBUF
void wrbuf_json_puts(WRBUF b, const char *str)
writes JSON text to WRBUF with escaping
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
void wrbuf_iconv_write(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
Converts buffer using iconv and appends to WRBUF.
void wrbuf_iconv_json_write(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
void wrbuf_iconv_puts(WRBUF b, yaz_iconv_t cd, const char *strz)
iconv converts C-string and appends to WRBUF
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
void wrbuf_iconv_json_puts(WRBUF b, yaz_iconv_t cd, const char *strz)
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
void wrbuf_json_write(WRBUF b, const char *cp, size_t sz)
writes JSON text to WRBUF with escaping
void wrbuf_iconv_write_cdata(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
Converts buffer using iconv and appends to WRBUF as XML CDATA.
Header for WRBUF (growing buffer)
#define xstrdup(s)
utility macro which calls xstrdup_f
#define xfree(x)
utility macro which calls xfree_f
#define xmalloc(x)
utility macro which calls malloc_f
Header for common YAZ utilities.