// Serialize a HTTP request static struct http_buf *http_serialize_request(struct http_request *r) { struct http_channel *c = r->channel; struct http_header *h; wrbuf_rewind(c->wrbuf); wrbuf_printf(c->wrbuf, "%s %s%s%s", r->method, r->path, *r->search ? "?" : "", r->search); wrbuf_printf(c->wrbuf, " HTTP/%s\r\n", r->http_version); for (h = r->headers; h; h = h->next) wrbuf_printf(c->wrbuf, "%s: %s\r\n", h->name, h->value); wrbuf_puts(c->wrbuf, "\r\n"); if (r->content_buf) wrbuf_write(c->wrbuf, r->content_buf, r->content_len); #if 0 yaz_log(YLOG_LOG, "WRITING TO PROXY:\n%s\n----", wrbuf_cstr(c->wrbuf)); #endif return http_buf_bywrbuf(c->http_server, c->wrbuf); }
static void cmd_server_status(struct http_channel *c) { int sessions = sessions_count(); int clients = clients_count(); int resultsets = resultsets_count(); response_open(c, "server-status"); wrbuf_printf(c->wrbuf, "\n <sessions>%u</sessions>\n", sessions); wrbuf_printf(c->wrbuf, " <clients>%u</clients>\n", clients); /* Only works if yaz has been compiled with enabling of this */ wrbuf_printf(c->wrbuf, " <resultsets>%u</resultsets>\n",resultsets); print_meminfo(c->wrbuf); /* TODO add all sessions status */ /* http_sessions_t http_sessions = c->http_sessions; */ /* struct http_session *p; */ /* yaz_mutex_enter(http_sessions->mutex); for (p = http_sessions->session_list; p; p = p->next) { p->activity_counter++; wrbuf_puts(c->wrbuf, "<session-status>\n"); wrbuf_printf(c->wrbuf, "<id>%s</id>\n", p->session_id); yaz_mutex_leave(http_sessions->mutex); session_status(c, p); wrbuf_puts(c->wrbuf, "</session-status>\n"); yaz_mutex_enter(http_sessions->mutex); p->activity_counter--; } yaz_mutex_leave(http_sessions->mutex); */ response_close(c, "server-status"); xmalloc_trav(0); }
static void yaz_apt_to_wrbuf(WRBUF b, const Z_AttributesPlusTerm *zapt) { yaz_attributes_to_wrbuf(b, zapt->attributes); switch (zapt->term->which) { case Z_Term_general: yaz_encode_pqf_term(b, (const char *)zapt->term->u.general->buf, zapt->term->u.general->len); break; case Z_Term_characterString: wrbuf_puts(b, "@term string "); yaz_encode_pqf_term(b, zapt->term->u.characterString, strlen(zapt->term->u.characterString)); break; case Z_Term_numeric: wrbuf_printf(b, "@term numeric " ODR_INT_PRINTF " ", *zapt->term->u.numeric); break; case Z_Term_null: wrbuf_puts(b, "@term null x"); break; default: wrbuf_printf(b, "@term null unknown%d ", zapt->term->which); } }
static void termlist_response(struct http_channel *c, struct http_session *s, const char *cmd_status) { struct http_request *rq = c->request; const char *name = http_argbyname(rq, "name"); const char *nums = http_argbyname(rq, "num"); int version = get_version(rq); int num = 15; int status; if (nums) num = atoi(nums); status = session_active_clients(s->psession); response_open_no_status(c, "termlist"); /* new protocol add a status to response. Triggered by a status parameter */ if (cmd_status != 0) { wrbuf_printf(c->wrbuf, "<status>%s</status>\n", cmd_status); } wrbuf_printf(c->wrbuf, "<activeclients>%d</activeclients>\n", status); perform_termlist(c, s->psession, name, num, version); response_close(c, "termlist"); }
/** \brief adds a attribute value to the element name if it is plain chars If not, and if the attribute name is not null, it will append a attribute element with the value if attribute name is null it will return a non-zero value meaning it couldnt handle the value. */ static int element_name_append_attribute_value( yaz_marc_t mt, WRBUF buffer, const char *attribute_name, char *code_data, size_t code_len) { /* TODO Map special codes to something possible for XML ELEMENT names */ int encode = 0; size_t index = 0; int success = 0; for (index = 0; index < code_len; index++) { if (!((code_data[index] >= '0' && code_data[index] <= '9') || (code_data[index] >= 'a' && code_data[index] <= 'z') || (code_data[index] >= 'A' && code_data[index] <= 'Z'))) encode = 1; } /* Add as attribute */ if (encode && attribute_name) wrbuf_printf(buffer, " %s=\"", attribute_name); if (!encode || attribute_name) wrbuf_iconv_write_cdata(buffer, mt->iconv_cd, code_data, code_len); else success = -1; if (encode && attribute_name) wrbuf_printf(buffer, "\""); /* return error if we couldn't handle it.*/ return success; }
void yaz_query_to_wrbuf(WRBUF b, const Z_Query *q) { assert(q); assert(b); switch (q->which) { case Z_Query_type_1: case Z_Query_type_101: wrbuf_printf(b,"RPN "); yaz_rpnquery_to_wrbuf(b, q->u.type_1); break; case Z_Query_type_2: wrbuf_printf(b, "CCL %.*s", q->u.type_2->len, q->u.type_2->buf); break; case Z_Query_type_100: wrbuf_printf(b, "Z39.58 %.*s", q->u.type_100->len, q->u.type_100->buf); break; case Z_Query_type_104: if (q->u.type_104->which == Z_External_CQL) wrbuf_printf(b, "CQL %s", q->u.type_104->u.cql); else wrbuf_printf(b,"UNKNOWN type 104 query %d", q->u.type_104->which); } }
static void session_status(struct http_channel *c, struct http_session *s) { size_t session_nmem; wrbuf_printf(c->wrbuf, "<http_count>%u</http_count>\n", s->activity_counter); wrbuf_printf(c->wrbuf, "<http_nmem>%zu</http_nmem>\n", nmem_total(s->nmem) ); session_nmem = session_get_memory_status(s->psession); wrbuf_printf(c->wrbuf, "<session_nmem>%zu</session_nmem>\n", session_nmem); }
static int convert_xslt(void *vinfo, WRBUF record, WRBUF wr_error) { int ret = 0; struct xslt_info *info = vinfo; xmlDocPtr doc = xmlParseMemory(wrbuf_buf(record), wrbuf_len(record)); if (!doc) { wrbuf_printf(wr_error, "xmlParseMemory failed"); ret = -1; } else { xmlDocPtr xsp_doc = xmlCopyDoc(info->xsp_doc, 1); xsltStylesheetPtr xsp = xsltParseStylesheetDoc(xsp_doc); xmlDocPtr res = xsltApplyStylesheet(xsp, doc, info->xsl_parms); if (res) { xmlChar *out_buf = 0; int out_len; #if HAVE_XSLTSAVERESULTTOSTRING xsltSaveResultToString(&out_buf, &out_len, res, xsp); #else xmlDocDumpFormatMemory (res, &out_buf, &out_len, 1); #endif if (!out_buf) { wrbuf_printf(wr_error, "xsltSaveResultToString failed"); ret = -1; } else { wrbuf_rewind(record); wrbuf_write(record, (const char *) out_buf, out_len); xmlFree(out_buf); } xmlFreeDoc(res); } else { wrbuf_printf(wr_error, "xsltApplyStylesheet failed"); ret = -1; } xmlFreeDoc(doc); xsltFreeStylesheet(xsp); /* frees xsp_doc too */ } return ret; }
void yaz_query_to_wrbuf(WRBUF b, const Z_Query *q) { assert(q); assert(b); switch (q->which) { case Z_Query_type_1: case Z_Query_type_101: wrbuf_puts(b,"RPN "); yaz_rpnquery_to_wrbuf(b, q->u.type_1); break; case Z_Query_type_2: wrbuf_puts(b, "CCL "); wrbuf_write(b, (const char *) q->u.type_2->buf, q->u.type_2->len); break; case Z_Query_type_100: wrbuf_puts(b, "Z39.58 "); wrbuf_write(b, (const char *) q->u.type_100->buf, q->u.type_100->len); break; case Z_Query_type_104: if (q->u.type_104->which == Z_External_CQL) { wrbuf_puts(b, "CQL "); wrbuf_puts(b, q->u.type_104->u.cql); } else wrbuf_printf(b,"UNKNOWN type 104 query %d", q->u.type_104->which); } }
static void *construct_select(const xmlNode *ptr, const char *path, WRBUF wr_error) { if (strcmp((const char *) ptr->name, "select")) return 0; else { NMEM nmem = nmem_create(); struct select_info *info = nmem_malloc(nmem, sizeof(*info)); const char *attr_str; const char *xpath = 0; info->nmem = nmem; info->xpath_expr = 0; attr_str = yaz_xml_get_prop(ptr, "path%s", &xpath); if (attr_str) { wrbuf_printf(wr_error, "Bad attribute '%s'" "Expected xpath.", attr_str); nmem_destroy(nmem); return 0; } if (xpath) info->xpath_expr = nmem_strdup(nmem, xpath); return info; } }
void yaz_scan_to_wrbuf(WRBUF b, const Z_AttributesPlusTerm *zapt, const Odr_oid *attrbute_set) { /* should print attr set here */ wrbuf_printf(b, "RPN "); yaz_apt_to_wrbuf(b, zapt); }
static void response_close(struct http_channel *c, const char *command) { struct http_response *rs = c->response; wrbuf_printf(c->wrbuf, "</%s>", command); rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf)); http_send_response(c); }
yaz_record_conv_t conv_configure(const char *xmlstring, WRBUF w) { xmlDocPtr doc = xmlParseMemory(xmlstring, strlen(xmlstring)); if (!doc) { wrbuf_printf(w, "xmlParseMemory"); return 0; } else { xmlNodePtr ptr = xmlDocGetRootElement(doc); yaz_record_conv_t p = yaz_record_conv_create(); if (p) { const char *srcdir = getenv("srcdir"); if (srcdir) yaz_record_conv_set_path(p, srcdir); } if (!ptr) { wrbuf_printf(w, "xmlDocGetRootElement"); yaz_record_conv_destroy(p); p = 0; } else if (!p) { wrbuf_printf(w, "yaz_record_conv_create"); } else { int r = yaz_record_conv_configure(p, ptr); if (r) { wrbuf_puts(w, yaz_record_conv_get_error(p)); yaz_record_conv_destroy(p); p = 0; } } xmlFreeDoc(doc); return p; } }
int yaz_marc_write_trailer(yaz_marc_t mt, WRBUF wr) { if (mt->enable_collection == collection_second) { switch(mt->output_format) { case YAZ_MARC_MARCXML: case YAZ_MARC_TURBOMARC: wrbuf_printf(wr, "</collection>\n"); break; case YAZ_MARC_XCHANGE: wrbuf_printf(wr, "</collection>\n"); break; } } return 0; }
static void write_metadata(WRBUF w, struct conf_service *service, struct record_metadata **ml, int full, int indent) { int imeta; for (imeta = 0; imeta < service->num_metadata; imeta++) { struct conf_metadata *cmd = &service->metadata[imeta]; struct record_metadata *md; if (!cmd->brief && !full) continue; for (md = ml[imeta]; md; md = md->next) { struct record_metadata_attr *attr = md->attributes; int i; for (i = 0; i < indent; i++) wrbuf_putc(w, ' '); wrbuf_printf(w, "<md-%s", cmd->name); for (; attr; attr = attr->next) { wrbuf_printf(w, " %s=\"", attr->name); wrbuf_xmlputs(w, attr->value); wrbuf_puts(w, "\""); } wrbuf_puts(w, ">"); switch (cmd->type) { case Metadata_type_generic: wrbuf_xmlputs(w, md->data.text.disp); break; case Metadata_type_year: wrbuf_printf(w, "%d", md->data.number.min); if (md->data.number.min != md->data.number.max) wrbuf_printf(w, "-%d", md->data.number.max); break; default: wrbuf_puts(w, "[can't represent]"); break; } wrbuf_printf(w, "</md-%s>\n", cmd->name); } } }
static void yaz_attribute_element_to_wrbuf(WRBUF b, const Z_AttributeElement *element) { int i; wrbuf_puts(b, "@attr "); if (element->attributeSet) { char oid_name_str[OID_STR_MAX]; const char *setname = yaz_oid_to_string_buf(element->attributeSet, 0, oid_name_str); if (setname) { wrbuf_puts(b, setname); wrbuf_puts(b, " "); } } wrbuf_printf(b, ODR_INT_PRINTF "=", *element->attributeType); switch (element->which) { case Z_AttributeValue_numeric: wrbuf_printf(b, ODR_INT_PRINTF, *element->value.numeric); break; case Z_AttributeValue_complex: for (i = 0; i < element->value.complex->num_list; i++) { if (i) wrbuf_puts(b, ","); if (element->value.complex->list[i]->which == Z_StringOrNumeric_string) wrbuf_puts(b, element->value.complex->list[i]->u.string); else if (element->value.complex->list[i]->which == Z_StringOrNumeric_numeric) wrbuf_printf(b, ODR_INT_PRINTF, *element->value.complex->list[i]->u.numeric); } break; default: wrbuf_puts(b, "@attr 1=unknown"); } wrbuf_puts(b, " "); }
void yaz_encode_pqf_term(WRBUF b, const char *term, int len) { int i; for (i = 0; i < len; i++) if (strchr(" \"{", term[i])) break; if (i == len && i) wrbuf_printf(b, "%.*s ", len, term); else { wrbuf_putc(b, '"'); for (i = 0; i<len; i++) { if (term[i] == '"') wrbuf_putc(b, '\\'); wrbuf_putc(b, term[i]); } wrbuf_printf(b, "\" "); } }
static void yaz_rpnstructure_to_wrbuf(WRBUF b, const Z_RPNStructure *zs) { if (zs->which == Z_RPNStructure_complex) { Z_Operator *op = zs->u.complex->roperator; wrbuf_printf(b, "@%s ", complex_op_name(op) ); if (op->which== Z_Operator_prox) { if (!op->u.prox->exclusion) wrbuf_putc(b, 'n'); else if (*op->u.prox->exclusion) wrbuf_putc(b, '1'); else wrbuf_putc(b, '0'); wrbuf_printf(b, " " ODR_INT_PRINTF " %d " ODR_INT_PRINTF " ", *op->u.prox->distance, *op->u.prox->ordered, *op->u.prox->relationType); switch(op->u.prox->which) { case Z_ProximityOperator_known: wrbuf_putc(b, 'k'); break; case Z_ProximityOperator_private: wrbuf_putc(b, 'p'); break; default: wrbuf_printf(b, "%d", op->u.prox->which); } if (op->u.prox->u.known) wrbuf_printf(b, " " ODR_INT_PRINTF " ", *op->u.prox->u.known); else wrbuf_printf(b, " 0 "); } yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s1); yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s2); } else if (zs->which == Z_RPNStructure_simple) { if (zs->u.simple->which == Z_Operand_APT) yaz_apt_to_wrbuf(b, zs->u.simple->u.attributesPlusTerm); else if (zs->u.simple->which == Z_Operand_resultSetId) { wrbuf_printf(b, "@set "); yaz_encode_pqf_term(b, zs->u.simple->u.resultSetId, strlen(zs->u.simple->u.resultSetId)); } else wrbuf_printf (b, "(unknown simple structure)"); } else wrbuf_puts(b, "(unknown structure)"); }
void yaz_rpnquery_to_wrbuf(WRBUF b, const Z_RPNQuery *rpn) { if (rpn->attributeSetId) { char oid_name_str[OID_STR_MAX]; const char *oid_name = yaz_oid_to_string_buf(rpn->attributeSetId, 0, oid_name_str); if (oid_name) wrbuf_printf(b, "@attrset %s ", oid_name); } yaz_rpnstructure_to_wrbuf(b, rpn->RPNStructure); wrbuf_chop_right(b); }
static struct http_buf *http_serialize_response(struct http_channel *c, struct http_response *r) { struct http_header *h; wrbuf_rewind(c->wrbuf); wrbuf_printf(c->wrbuf, "HTTP/%s %s %s\r\n", c->version, r->code, r->msg); for (h = r->headers; h; h = h->next) wrbuf_printf(c->wrbuf, "%s: %s\r\n", h->name, h->value); if (r->payload) { wrbuf_printf(c->wrbuf, "Content-Length: %d\r\n", r->payload ? (int) strlen(r->payload) : 0); wrbuf_printf(c->wrbuf, "Content-Type: %s\r\n", r->content_type); if (!strcmp(r->content_type, "text/xml")) { xmlDoc *doc = xmlParseMemory(r->payload, strlen(r->payload)); if (doc) { xmlFreeDoc(doc); } else { yaz_log(YLOG_WARN, "Sending non-wellformed " "response (bug #1162"); yaz_log(YLOG_WARN, "payload: %s", r->payload); } } } wrbuf_puts(c->wrbuf, "\r\n"); if (r->payload) wrbuf_puts(c->wrbuf, r->payload); return http_buf_bywrbuf(c->http_server, c->wrbuf); }
static int convert_select(void *vinfo, WRBUF record, WRBUF wr_error) { int ret = 0; struct select_info *info = vinfo; xmlDocPtr doc = xmlParseMemory(wrbuf_buf(record), wrbuf_len(record)); if (!doc) { wrbuf_printf(wr_error, "xmlParseMemory failed"); ret = -1; } else { xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc); if (xpathCtx && info->xpath_expr) { xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar *) info->xpath_expr, xpathCtx); if (xpathObj) { xmlNodeSetPtr nodes = xpathObj->nodesetval; if (nodes) { int i; if (nodes->nodeNr > 0) wrbuf_rewind(record); for (i = 0; i < nodes->nodeNr; i++) { xmlNode *ptr = nodes->nodeTab[i]; if (ptr->type == XML_ELEMENT_NODE) ptr = ptr->children; for (; ptr; ptr = ptr->next) if (ptr->type == XML_TEXT_NODE) wrbuf_puts(record, (const char *) ptr->content); } } xmlXPathFreeObject(xpathObj); } xmlXPathFreeContext(xpathCtx); } xmlFreeDoc(doc); } return ret; }
void print_meminfo(WRBUF wrbuf) { struct mallinfo minfo; minfo = mallinfo(); wrbuf_printf(wrbuf, " <memory>\n" " <arena>%d</arena>\n" " <uordblks>%d</uordblks>\n" " <fordblks>%d</fordblks>\n" " <ordblks>%d</ordblks>\n" " <keepcost>%d</keepcost>\n" " <hblks>%d</hblks>\n" " <hblkhd>%d</hblkhd>\n" " <virt>%d</virt>\n" " <virtuse>%d</virtuse>\n" " </memory>\n", minfo.arena, minfo.uordblks, minfo.fordblks,minfo.ordblks, minfo.keepcost, minfo.hblks, minfo.hblkhd, minfo.arena + minfo.hblkhd, minfo.uordblks + minfo.hblkhd); }
static void yaz_attribute_element_to_wrbuf(WRBUF b, const Z_AttributeElement *element) { int i; char oid_name_str[OID_STR_MAX]; const char *setname = 0; char *sep = " "; /* optional space after attrset name */ if (element->attributeSet) { setname = yaz_oid_to_string_buf(element->attributeSet, 0, oid_name_str); } if (!setname) { setname = ""; sep = ""; } switch (element->which) { case Z_AttributeValue_numeric: wrbuf_printf(b,"@attr %s%s" ODR_INT_PRINTF "=" ODR_INT_PRINTF " ", setname, sep, *element->attributeType, *element->value.numeric); break; case Z_AttributeValue_complex: wrbuf_printf(b,"@attr %s%s\""ODR_INT_PRINTF "=", setname, sep, *element->attributeType); for (i = 0; i<element->value.complex->num_list; i++) { if (i) wrbuf_printf(b,","); if (element->value.complex->list[i]->which == Z_StringOrNumeric_string) wrbuf_printf (b, "%s", element->value.complex->list[i]->u.string); else if (element->value.complex->list[i]->which == Z_StringOrNumeric_numeric) wrbuf_printf (b, ODR_INT_PRINTF, *element->value.complex->list[i]->u.numeric); } wrbuf_printf(b, "\" "); break; default: wrbuf_printf (b, "@attr 1=unknown "); } }
void wrbuf_diags(WRBUF b, int num_diagnostics, Z_DiagRec **diags) { /* we only dump the first diag - that keeps the log cleaner. */ wrbuf_puts(b," ERROR "); if (diags[0]->which != Z_DiagRec_defaultFormat) wrbuf_puts(b,"(diag not in default format?)"); else { Z_DefaultDiagFormat *e = diags[0]->u.defaultFormat; if (e->condition) wrbuf_printf(b, ODR_INT_PRINTF " ",*e->condition); else wrbuf_puts(b, "?? "); if ((e->which==Z_DefaultDiagFormat_v2Addinfo) && (e->u.v2Addinfo)) wrbuf_puts(b, e->u.v2Addinfo); else if ((e->which==Z_DefaultDiagFormat_v3Addinfo) && (e->u.v3Addinfo)) wrbuf_puts(b, e->u.v3Addinfo); wrbuf_puts(b, " "); } }
static void write_subrecord(struct record *r, WRBUF w, struct conf_service *service, int show_details) { const char *name = session_setting_oneval( client_get_database(r->client), PZ_NAME); wrbuf_puts(w, " <location id=\""); wrbuf_xmlputs(w, client_get_id(r->client)); wrbuf_puts(w, "\"\n"); wrbuf_puts(w, " name=\""); wrbuf_xmlputs(w, *name ? name : "Unknown"); wrbuf_puts(w, "\" "); wrbuf_puts(w, "checksum=\""); wrbuf_printf(w, "%u", r->checksum); wrbuf_puts(w, "\">\n"); write_metadata(w, service, r->metadata, show_details, 2); wrbuf_puts(w, " </location>\n"); }
static void cmd_info(struct http_channel *c) { char yaz_version_str[20]; char yaz_sha1_str[42]; response_open_no_status(c, "info"); wrbuf_puts(c->wrbuf, "\n <version>\n"); wrbuf_puts(c->wrbuf, " <pazpar2"); #ifdef PAZPAR2_VERSION_SHA1 wrbuf_printf(c->wrbuf, " sha1=\"%s\"", PAZPAR2_VERSION_SHA1); #endif wrbuf_puts(c->wrbuf, ">"); wrbuf_xmlputs(c->wrbuf, VERSION); wrbuf_puts(c->wrbuf, "</pazpar2>\n"); yaz_version(yaz_version_str, yaz_sha1_str); wrbuf_puts(c->wrbuf, " <yaz compiled=\""); wrbuf_xmlputs(c->wrbuf, YAZ_VERSION); wrbuf_puts(c->wrbuf, "\" sha1=\""); wrbuf_xmlputs(c->wrbuf, yaz_sha1_str); wrbuf_puts(c->wrbuf, "\">"); wrbuf_xmlputs(c->wrbuf, yaz_version_str); wrbuf_puts(c->wrbuf, "</yaz>\n"); wrbuf_puts(c->wrbuf, " </version>\n"); #if HAVE_UNISTD_H { char hostname_str[64]; if (gethostname(hostname_str, sizeof(hostname_str)) == 0) { wrbuf_puts(c->wrbuf, " <host>"); wrbuf_xmlputs(c->wrbuf, hostname_str); wrbuf_puts(c->wrbuf, "</host>\n"); } } #endif info_services(c->server, c->wrbuf); response_close(c, "info"); }
static void error(struct http_response *rs, enum pazpar2_error_code code, const char *addinfo) { struct http_channel *c = rs->channel; WRBUF text = wrbuf_alloc(); const char *http_status = "417"; const char *msg = get_msg(code); rs->msg = nmem_strdup(c->nmem, msg); strcpy(rs->code, http_status); wrbuf_printf(text, HTTP_COMMAND_RESPONSE_PREFIX "<error code=\"%d\" msg=\"%s\">", (int) code, msg); if (addinfo) wrbuf_xmlputs(text, addinfo); wrbuf_puts(text, "</error>"); yaz_log(YLOG_WARN, "HTTP %s %s%s%s", http_status, msg, addinfo ? ": " : "" , addinfo ? addinfo : ""); rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(text)); wrbuf_destroy(text); http_send_response(c); }
/** \brief common MARC XML/Xchange/turbomarc writer \param mt handle \param wr WRBUF output \param ns XMLNS for the elements \param format record format (e.g. "MARC21") \param type record type (e.g. "Bibliographic") \param turbo =1 for turbomarc \retval 0 OK \retval -1 failure */ static int yaz_marc_write_marcxml_wrbuf(yaz_marc_t mt, WRBUF wr, const char *ns, const char *format, const char *type, int turbo) { struct yaz_marc_node *n; int identifier_length; const char *leader = 0; for (n = mt->nodes; n; n = n->next) if (n->which == YAZ_MARC_LEADER) { leader = n->u.leader; break; } if (!leader) return -1; if (!atoi_n_check(leader+11, 1, &identifier_length)) return -1; if (mt->enable_collection != no_collection) { if (mt->enable_collection == collection_first) { wrbuf_printf(wr, "<collection xmlns=\"%s\">\n", ns); mt->enable_collection = collection_second; } wrbuf_printf(wr, "<%s", record_name[turbo]); } else { wrbuf_printf(wr, "<%s xmlns=\"%s\"", record_name[turbo], ns); } if (format) wrbuf_printf(wr, " format=\"%.80s\"", format); if (type) wrbuf_printf(wr, " type=\"%.80s\"", type); wrbuf_printf(wr, ">\n"); for (n = mt->nodes; n; n = n->next) { struct yaz_marc_subfield *s; switch(n->which) { case YAZ_MARC_DATAFIELD: wrbuf_printf(wr, " <%s", datafield_name[turbo]); if (!turbo) wrbuf_printf(wr, " tag=\""); wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.datafield.tag, strlen(n->u.datafield.tag)); if (!turbo) wrbuf_printf(wr, "\""); if (n->u.datafield.indicator) { int i; for (i = 0; n->u.datafield.indicator[i]; i++) { wrbuf_printf(wr, " %s%d=\"", indicator_name[turbo], i+1); wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.datafield.indicator+i, 1); wrbuf_iconv_puts(wr, mt->iconv_cd, "\""); } } wrbuf_printf(wr, ">\n"); for (s = n->u.datafield.subfields; s; s = s->next) { size_t using_code_len = get_subfield_len(mt, s->code_data, identifier_length); wrbuf_printf(wr, " <%s", subfield_name[turbo]); if (!turbo) { wrbuf_printf(wr, " code=\""); wrbuf_iconv_write_cdata(wr, mt->iconv_cd, s->code_data, using_code_len); wrbuf_iconv_puts(wr, mt->iconv_cd, "\">"); } else { element_name_append_attribute_value(mt, wr, "code", s->code_data, using_code_len); wrbuf_puts(wr, ">"); } wrbuf_iconv_write_cdata(wr, mt->iconv_cd, s->code_data + using_code_len, strlen(s->code_data + using_code_len)); marc_iconv_reset(mt, wr); wrbuf_printf(wr, "</%s", subfield_name[turbo]); if (turbo) element_name_append_attribute_value(mt, wr, 0, s->code_data, using_code_len); wrbuf_puts(wr, ">\n"); } wrbuf_printf(wr, " </%s", datafield_name[turbo]); /* TODO Not CDATA */ if (turbo) wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.datafield.tag, strlen(n->u.datafield.tag)); wrbuf_printf(wr, ">\n"); break; case YAZ_MARC_CONTROLFIELD: wrbuf_printf(wr, " <%s", controlfield_name[turbo]); if (!turbo) { wrbuf_printf(wr, " tag=\""); wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.tag, strlen(n->u.controlfield.tag)); wrbuf_iconv_puts(wr, mt->iconv_cd, "\">"); } else { /* TODO convert special */ wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.tag, strlen(n->u.controlfield.tag)); wrbuf_iconv_puts(wr, mt->iconv_cd, ">"); } wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.data, strlen(n->u.controlfield.data)); marc_iconv_reset(mt, wr); wrbuf_printf(wr, "</%s", controlfield_name[turbo]); /* TODO convert special */ if (turbo) wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.tag, strlen(n->u.controlfield.tag)); wrbuf_puts(wr, ">\n"); break; case YAZ_MARC_COMMENT: wrbuf_printf(wr, "<!-- "); wrbuf_puts(wr, n->u.comment); wrbuf_printf(wr, " -->\n"); break; case YAZ_MARC_LEADER: wrbuf_printf(wr, " <%s>", leader_name[turbo]); wrbuf_iconv_write_cdata(wr, 0 , /* no charset conversion for leader */ n->u.leader, strlen(n->u.leader)); wrbuf_printf(wr, "</%s>\n", leader_name[turbo]); } } wrbuf_printf(wr, "</%s>\n", record_name[turbo]); return 0; }
int yaz_marc_write_line(yaz_marc_t mt, WRBUF wr) { struct yaz_marc_node *n; int identifier_length; const char *leader = 0; for (n = mt->nodes; n; n = n->next) if (n->which == YAZ_MARC_LEADER) { leader = n->u.leader; break; } if (!leader) return -1; if (!atoi_n_check(leader+11, 1, &identifier_length)) return -1; for (n = mt->nodes; n; n = n->next) { struct yaz_marc_subfield *s; switch(n->which) { case YAZ_MARC_DATAFIELD: wrbuf_printf(wr, "%s %s", n->u.datafield.tag, n->u.datafield.indicator); for (s = n->u.datafield.subfields; s; s = s->next) { size_t using_code_len = get_subfield_len(mt, s->code_data, identifier_length); wrbuf_puts (wr, mt->subfield_str); wrbuf_iconv_write(wr, mt->iconv_cd, s->code_data, using_code_len); wrbuf_iconv_puts(wr, mt->iconv_cd, " "); wrbuf_iconv_puts(wr, mt->iconv_cd, s->code_data + using_code_len); marc_iconv_reset(mt, wr); } wrbuf_puts (wr, mt->endline_str); break; case YAZ_MARC_CONTROLFIELD: wrbuf_printf(wr, "%s", n->u.controlfield.tag); wrbuf_iconv_puts(wr, mt->iconv_cd, " "); wrbuf_iconv_puts(wr, mt->iconv_cd, n->u.controlfield.data); marc_iconv_reset(mt, wr); wrbuf_puts (wr, mt->endline_str); break; case YAZ_MARC_COMMENT: wrbuf_puts(wr, "("); wrbuf_iconv_write(wr, mt->iconv_cd, n->u.comment, strlen(n->u.comment)); marc_iconv_reset(mt, wr); wrbuf_puts(wr, ")\n"); break; case YAZ_MARC_LEADER: wrbuf_printf(wr, "%s\n", n->u.leader); } } wrbuf_puts(wr, "\n"); return 0; }
int yaz_marc_write_json(yaz_marc_t mt, WRBUF w) { int identifier_length; struct yaz_marc_node *n; const char *leader = 0; int first = 1; wrbuf_puts(w, "{\n"); for (n = mt->nodes; n; n = n->next) if (n->which == YAZ_MARC_LEADER) leader = n->u.leader; if (!leader) return -1; if (!atoi_n_check(leader+11, 1, &identifier_length)) return -1; wrbuf_puts(w, "\t\"leader\":\""); wrbuf_json_puts(w, leader); wrbuf_puts(w, "\",\n"); wrbuf_puts(w, "\t\"fields\":\n\t[\n"); for (n = mt->nodes; n; n = n->next) { struct yaz_marc_subfield *s; const char *sep = ""; switch (n->which) { case YAZ_MARC_LEADER: case YAZ_MARC_COMMENT: break; case YAZ_MARC_CONTROLFIELD: if (first) first = 0; else wrbuf_puts(w, ",\n"); wrbuf_puts(w, "\t\t{\n\t\t\t\""); wrbuf_iconv_json_puts(w, mt->iconv_cd, n->u.controlfield.tag); wrbuf_puts(w, "\":\""); wrbuf_iconv_json_puts(w, mt->iconv_cd, n->u.controlfield.data); wrbuf_puts(w, "\"\n\t\t}"); break; case YAZ_MARC_DATAFIELD: if (first) first = 0; else wrbuf_puts(w, ",\n"); wrbuf_puts(w, "\t\t{\n\t\t\t\""); wrbuf_json_puts(w, n->u.datafield.tag); wrbuf_puts(w, "\":\n\t\t\t{\n\t\t\t\t\"subfields\":\n\t\t\t\t[\n"); for (s = n->u.datafield.subfields; s; s = s->next) { size_t using_code_len = get_subfield_len(mt, s->code_data, identifier_length); wrbuf_puts(w, sep); sep = ",\n"; wrbuf_puts(w, "\t\t\t\t\t{\n\t\t\t\t\t\t\""); wrbuf_iconv_json_write(w, mt->iconv_cd, s->code_data, using_code_len); wrbuf_puts(w, "\":\""); wrbuf_iconv_json_puts(w, mt->iconv_cd, s->code_data + using_code_len); wrbuf_puts(w, "\"\n\t\t\t\t\t}"); } wrbuf_puts(w, "\n\t\t\t\t]"); if (n->u.datafield.indicator[0]) { int i; for (i = 0; n->u.datafield.indicator[i]; i++) { wrbuf_printf(w, ",\n\t\t\t\t\"ind%d\":\"%c\"", i + 1, n->u.datafield.indicator[i]); } } wrbuf_puts(w, "\n\t\t\t}\n"); wrbuf_puts(w, "\n\t\t}"); break; } } wrbuf_puts(w, "\n\t]\n"); wrbuf_puts(w, "}\n"); return 0; }