📄 srw.c
字号:
/* * Copyright (c) 2002-2003, Index Data. * See the file LICENSE for details. * * $Id: srw.c,v 1.15 2003/05/12 22:36:10 adam Exp $ */#include <yaz/srw.h>#if HAVE_XML2#include <libxml/parser.h>#include <libxml/tree.h>static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len){ if (val) { xmlDocPtr doc = xmlParseMemory(val,len); if (doc) { xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0); xmlNodePtr t = xmlDocGetRootElement(doc); xmlAddChild(c, xmlCopyNode(t,1)); xmlFreeDoc(doc); } }}static void add_xsd_string_n(xmlNodePtr ptr, const char *elem, char *val, int len){ if (val) { xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0); xmlNodePtr t = xmlNewTextLen(val, len); xmlAddChild(c, t); }}static void add_xsd_string(xmlNodePtr ptr, const char *elem, char *val){ if (val) xmlNewChild(ptr, 0, elem, val);}static void add_xsd_integer(xmlNodePtr ptr, const char *elem, int *val){ if (val) { char str[30]; sprintf(str, "%d", *val); xmlNewChild(ptr, 0, elem, str); }}static int match_element(xmlNodePtr ptr, const char *elem){ if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, elem)) return 1; return 0;}#define CHECK_TYPE 0static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len){#if CHECK_TYPE struct _xmlAttr *attr;#endif if (!match_element(ptr, elem)) return 0;#if CHECK_TYPE for (attr = ptr->properties; attr; attr = attr->next) if (!strcmp(attr->name, "type") && attr->children && attr->children->type == XML_TEXT_NODE) { const char *t = strchr(attr->children->content, ':'); if (t) t = t + 1; else t = attr->children->content; if (!strcmp(t, "string")) break; } if (!attr) return 0;#endif ptr = ptr->children; if (!ptr || ptr->type != XML_TEXT_NODE) return 0; *val = odr_strdup(o, ptr->content); if (len) *len = strlen(ptr->content); return 1;}static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, char **val){ return match_xsd_string_n(ptr, elem, o, val, 0);}static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len){ xmlBufferPtr buf; if (!match_element(ptr, elem)) return 0; ptr = ptr->children; if (!ptr) return 0; buf = xmlBufferCreate(); xmlNodeDump(buf, ptr->doc, ptr, 0, 0); *val = odr_malloc(o, buf->use+1); memcpy (*val, buf->content, buf->use); (*val)[buf->use] = '\0'; if (len) *len = buf->use; xmlBufferFree(buf); return 1;} static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val){#if CHECK_TYPE struct _xmlAttr *attr;#endif if (!match_element(ptr, elem)) return 0;#if CHECK_TYPE for (attr = ptr->properties; attr; attr = attr->next) if (!strcmp(attr->name, "type") && attr->children && attr->children->type == XML_TEXT_NODE) { const char *t = strchr(attr->children->content, ':'); if (t) t = t + 1; else t = attr->children->content; if (!strcmp(t, "integer")) break; } if (!attr) return 0;#endif ptr = ptr->children; if (!ptr || ptr->type != XML_TEXT_NODE) return 0; *val = odr_intdup(o, atoi(ptr->content)); return 1;}static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, int *num, void *client_data, const char *ns){ if (o->direction == ODR_DECODE) { int i; xmlNodePtr ptr; *num = 0; for (ptr = pptr->children; ptr; ptr = ptr->next) { if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, "record")) (*num)++; } if (!*num) return 1; *recs = odr_malloc(o, *num * sizeof(**recs)); for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++) { if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, "record")) { xmlNodePtr rptr; (*recs)[i].recordSchema = 0; (*recs)[i].recordPacking = Z_SRW_recordPacking_string; (*recs)[i].recordData_buf = 0; (*recs)[i].recordData_len = 0; (*recs)[i].recordPosition = 0; for (rptr = ptr->children; rptr; rptr = rptr->next) { if (match_xsd_string(rptr, "recordSchema", o, &(*recs)[i].recordSchema)) ; else if (match_xsd_string_n(rptr, "recordData", o, &(*recs)[i].recordData_buf, &(*recs)[i].recordData_len)) ; else if (match_xsd_XML_n(rptr, "recordXML", o, &(*recs)[i].recordData_buf, &(*recs)[i].recordData_len)) (*recs)[i].recordPacking = Z_SRW_recordPacking_XML; else if (match_xsd_integer(rptr, "recordPosition", o, &(*recs)[i].recordPosition)) ; } } } } else if (o->direction == ODR_ENCODE) { int i; for (i = 0; i < *num; i++) { xmlNodePtr rptr = xmlNewChild(pptr, 0, "record", 0); add_xsd_string(rptr, "recordSchema", (*recs)[i].recordSchema); switch((*recs)[i].recordPacking) { case Z_SRW_recordPacking_string: add_xsd_string_n(rptr, "recordData", (*recs)[i].recordData_buf, (*recs)[i].recordData_len); break; case Z_SRW_recordPacking_XML: add_XML_n(rptr, "recordXML", (*recs)[i].recordData_buf, (*recs)[i].recordData_len); break; } add_xsd_integer(rptr, "recordPosition", (*recs)[i].recordPosition); } } return 0;}static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, int *num, void *client_data, const char *ns){ if (o->direction == ODR_DECODE) { int i; xmlNodePtr ptr; *num = 0; for (ptr = pptr->children; ptr; ptr = ptr->next) { if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, "diagnostic")) (*num)++; } if (!*num) return 1; *recs = odr_malloc(o, *num * sizeof(**recs)); for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++) { if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, "diagnostic")) { xmlNodePtr rptr; (*recs)[i].code = 0; (*recs)[i].details = 0; for (rptr = ptr->children; rptr; rptr = rptr->next) { if (match_xsd_integer(rptr, "code", o, &(*recs)[i].code)) ; else if (match_xsd_string(rptr, "details", o, &(*recs)[i].details)) ; } i++; } } } else if (o->direction == ODR_ENCODE) { int i; for (i = 0; i < *num; i++) { xmlNodePtr rptr = xmlNewChild(pptr, 0, "diagnostic", 0); add_xsd_integer(rptr, "code", (*recs)[i].code); add_xsd_string(rptr, "details", (*recs)[i].details); } } return 0;}int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns){ xmlNodePtr pptr = vptr; if (o->direction == ODR_DECODE) { xmlNodePtr method = pptr->children; while (method && method->type == XML_TEXT_NODE) method = method->next; if (!method || method->type != XML_ELEMENT_NODE) return -1; if (!strcmp(method->name, "searchRetrieveRequest")) { Z_SRW_PDU **p = handler_data; xmlNodePtr ptr = method->children; Z_SRW_searchRetrieveRequest *req; *p = odr_malloc(o, sizeof(**p)); (*p)->which = Z_SRW_searchRetrieve_request; req = (*p)->u.request = odr_malloc(o, sizeof(*req)); req->query_type = Z_SRW_query_type_cql; req->query.cql = 0; req->sort_type = Z_SRW_sort_type_none; req->sort.none = 0; req->startRecord = 0; req->maximumRecords = 0; req->recordSchema = 0; req->recordPacking = 0; req->database = 0; for (; ptr; ptr = ptr->next) { if (match_xsd_string(ptr, "query", o, &req->query.cql)) req->query_type = Z_SRW_query_type_cql; else if (match_xsd_string(ptr, "pQuery", o, &req->query.pqf)) req->query_type = Z_SRW_query_type_pqf; else if (match_xsd_string(ptr, "xQuery", o, &req->query.xcql)) req->query_type = Z_SRW_query_type_xcql; else if (match_xsd_string(ptr, "sortKeys", o, &req->sort.sortKeys)) req->sort_type = Z_SRW_sort_type_sort; else if (match_xsd_string(ptr, "recordSchema", o, &req->recordSchema)) ; else if (match_xsd_string(ptr, "recordPacking", o, &req->recordPacking)) ; else if (match_xsd_integer(ptr, "startRecord", o, &req->startRecord)) ; else if (match_xsd_integer(ptr, "maximumRecords", o, &req->maximumRecords)) ; else if (match_xsd_string(ptr, "database", o, &req->database)) ; /* missing is xQuery, xSortKeys .. */ } } else if (!strcmp(method->name, "searchRetrieveResponse")) { Z_SRW_PDU **p = handler_data; xmlNodePtr ptr = method->children; Z_SRW_searchRetrieveResponse *res; *p = odr_malloc(o, sizeof(**p)); (*p)->which = Z_SRW_searchRetrieve_response; res = (*p)->u.response = odr_malloc(o, sizeof(*res)); res->numberOfRecords = 0; res->resultSetId = 0; res->resultSetIdleTime = 0; res->records = 0; res->num_records = 0; res->diagnostics = 0; res->num_diagnostics = 0; res->nextRecordPosition = 0; for (; ptr; ptr = ptr->next) { if (match_xsd_integer(ptr, "numberOfRecords", o, &res->numberOfRecords)) ; else if (match_xsd_string(ptr, "resultSetId", o, &res->resultSetId)) ; else if (match_xsd_integer(ptr, "resultSetIdleTime", o, &res->resultSetIdleTime)) ; else if (match_element(ptr, "records")) yaz_srw_records(o, ptr, &res->records, &res->num_records, client_data, ns); else if (match_element(ptr, "diagnostics")) yaz_srw_diagnostics(o, ptr, &res->diagnostics, &res->num_diagnostics, client_data, ns); else if (match_xsd_integer(ptr, "nextRecordPosition", o, &res->nextRecordPosition)) ; } } else if (!strcmp(method->name, "explainRequest")) { Z_SRW_PDU **p = handler_data; Z_SRW_explainRequest *req; *p = odr_malloc(o, sizeof(**p)); (*p)->which = Z_SRW_explain_request; req = (*p)->u.explain_request = odr_malloc(o, sizeof(*req)); req->dummy = 0; } else if (!strcmp(method->name, "explainResponse")) { Z_SRW_PDU **p = handler_data; Z_SRW_explainResponse *res; xmlNodePtr ptr = method->children; *p = odr_malloc(o, sizeof(**p)); (*p)->which = Z_SRW_explain_response; res = (*p)->u.explain_response = odr_malloc(o, sizeof(*res)); res->explainData_buf = 0; res->explainData_len = 0; res->explainPacking = Z_SRW_recordPacking_string; for (; ptr; ptr = ptr->next) { match_xsd_string_n(ptr, "Explain", o, &res->explainData_buf, &res->explainData_len); } } else return -1; } else if (o->direction == ODR_ENCODE) { Z_SRW_PDU **p = handler_data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -