X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-c.c;h=44a56460dc23588aeb8a58530d7faaaf3d163444;hp=e05de203c4e9b4c6baea7152605a8e80c1ebdf6a;hb=5e240678f83361786067bdb9741ad5302b5bc5d7;hpb=a5ebdfbdd3845ef01e1c2e8d19daae12fc2f036e diff --git a/src/zoom-c.c b/src/zoom-c.c index e05de20..44a5646 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2009 Index Data + * Copyright (C) 1995-2010 Index Data * See the file LICENSE for details. */ /** @@ -1011,6 +1011,20 @@ ZOOM_API(int) return 0; } +static void ZOOM_record_release(ZOOM_record rec) +{ + if (!rec) + return; + if (rec->wrbuf) + wrbuf_destroy(rec->wrbuf); +#if YAZ_HAVE_XML2 + if (rec->xml_mem) + xmlFree(rec->xml_mem); +#endif + if (rec->odr) + odr_destroy(rec->odr); +} + ZOOM_API(void) ZOOM_resultset_cache_reset(ZOOM_resultset r) { @@ -1020,8 +1034,7 @@ ZOOM_API(void) ZOOM_record_cache rc; for (rc = r->record_hash[i]; rc; rc = rc->next) { - if (rc->rec.wrbuf) - wrbuf_destroy(rc->rec.wrbuf); + ZOOM_record_release(&rc->rec); } r->record_hash[i] = 0; } @@ -1071,7 +1084,7 @@ static void resultset_destroy(ZOOM_resultset r) ZOOM_API(size_t) ZOOM_resultset_size(ZOOM_resultset r) { - yaz_log(log_details, "ZOOM_resultset_size r=%p count=%d", + yaz_log(log_details, "ZOOM_resultset_size r=%p count=" ODR_INT_PRINTF, r, r->size); return r->size; } @@ -1213,14 +1226,14 @@ static zoom_ret do_connect(ZOOM_connection c) if (c->cs && c->cs->protocol == PROTO_HTTP) { #if YAZ_HAVE_XML2 - const char *path = 0; + const char *db = 0; c->proto = PROTO_HTTP; - cs_get_host_args(c->host_port, &path); + cs_get_host_args(c->host_port, &db); xfree(c->path); - c->path = (char*) xmalloc(strlen(path)+2); - c->path[0] = '/'; - strcpy(c->path+1, path); + + c->path = xmalloc(strlen(db) * 3 + 2); + yaz_encode_sru_dbpath_buf(c->path, db); #else set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW"); do_close(c); @@ -1445,11 +1458,7 @@ static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr) char *fdatabase = 0; if (database) - { - fdatabase = (char *) odr_malloc(c->odr_out, strlen(database)+2); - strcpy(fdatabase, "/"); - strcat(fdatabase, database); - } + fdatabase = yaz_encode_sru_dbpath_odr(c->odr_out, database); gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port, fdatabase ? fdatabase : c->path); @@ -1635,12 +1644,19 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c) yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8"); if (cd) { + int r; search_req->query = yaz_copy_Z_Query(search_req->query, c->odr_out); - yaz_query_charset_convert_rpnquery(search_req->query->u.type_1, - c->odr_out, cd); + r = yaz_query_charset_convert_rpnquery_check( + search_req->query->u.type_1, + c->odr_out, cd); yaz_iconv_close(cd); + if (r) + { /* query could not be char converted */ + set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0); + return zoom_complete; + } } } } @@ -1777,6 +1793,10 @@ ZOOM_API(ZOOM_record) nrec = (ZOOM_record) xmalloc(sizeof(*nrec)); nrec->odr = odr_createmem(ODR_DECODE); nrec->wrbuf = 0; +#if YAZ_HAVE_XML2 + nrec->xml_mem = 0; + nrec->xml_size = 0; +#endif odr_setbuf(nrec->odr, buf, size, 0); z_NamePlusRecord(nrec->odr, &nrec->npr, 0, 0); @@ -1824,11 +1844,7 @@ ZOOM_API(ZOOM_record) ZOOM_API(void) ZOOM_record_destroy(ZOOM_record rec) { - if (!rec) - return; - if (rec->wrbuf) - wrbuf_destroy(rec->wrbuf); - odr_destroy(rec->odr); + ZOOM_record_release(rec); xfree(rec); } @@ -1845,7 +1861,7 @@ static yaz_iconv_t iconv_create_charset(const char *record_charset) { /* Use "from,to" or just "from" */ const char *cp = strchr(record_charset, ','); - int clen = strlen(record_charset); + size_t clen = strlen(record_charset); if (cp && cp[1]) { strncpy( to, cp+1, sizeof(to)-1); @@ -2055,14 +2071,42 @@ ZOOM_API(int) return 0; } +static const char *get_record_format(ZOOM_record rec, int *len, + Z_NamePlusRecord *npr, + int marctype, const char *charset, + const char *format) +{ + const char *res = return_record(rec, len, npr, marctype, charset); +#if YAZ_HAVE_XML2 + if (*format == '1' && len) + { + /* try to XML format res */ + xmlDocPtr doc; + xmlKeepBlanksDefault(0); /* get get xmlDocFormatMemory to work! */ + doc = xmlParseMemory(res, *len); + if (doc) + { + if (rec->xml_mem) + xmlFree(rec->xml_mem); + xmlDocDumpFormatMemory(doc, &rec->xml_mem, &rec->xml_size, 1); + xmlFreeDoc(doc); + res = (char *) rec->xml_mem; + *len = rec->xml_size; + } + } +#endif + return res; +} + + ZOOM_API(const char *) ZOOM_record_get(ZOOM_record rec, const char *type_spec, int *len) { char type[40]; char charset[40]; - char xpath[512]; + char format[3]; const char *cp; - int i; + size_t i; Z_NamePlusRecord *npr; if (len) @@ -2075,41 +2119,43 @@ ZOOM_API(const char *) return 0; cp = type_spec; - for (i = 0; cp[i] && i < sizeof(type)-1; i++) - { - if (cp[i] == ';' || cp[i] == ' ') - break; + for (i = 0; cp[i] && cp[i] != ';' && cp[i] != ' ' && i < sizeof(type)-1; + i++) type[i] = cp[i]; - } type[i] = '\0'; charset[0] = '\0'; - while (type_spec[i] == ';') + format[0] = '\0'; + while (1) { + while (cp[i] == ' ') + i++; + if (cp[i] != ';') + break; i++; - while (type_spec[i] == ' ') + while (cp[i] == ' ') i++; - if (!strncmp(type_spec+i, "charset=", 8)) + if (!strncmp(cp + i, "charset=", 8)) { - int j = 0; + size_t j = 0; i = i + 8; /* skip charset= */ - for (j = 0; type_spec[i] && j < sizeof(charset)-1; i++, j++) + for (j = 0; cp[i] && cp[i] != ';' && cp[i] != ' '; i++) { - if (type_spec[i] == ';' || type_spec[i] == ' ') - break; - charset[j] = cp[i]; + if (j < sizeof(charset)-1) + charset[j++] = cp[i]; } charset[j] = '\0'; } - else if (!strncmp(type_spec+i, "xpath=", 6)) + else if (!strncmp(cp + i, "format=", 7)) { - int j = 0; - i = i + 6; - for (j = 0; type_spec[i] && j < sizeof(xpath)-1; i++, j++) - xpath[j] = cp[i]; - xpath[j] = '\0'; + size_t j = 0; + i = i + 7; + for (j = 0; cp[i] && cp[i] != ';' && cp[i] != ' '; i++) + { + if (j < sizeof(format)-1) + format[j++] = cp[i]; + } + format[j] = '\0'; } - while (type_spec[i] == ' ') - i++; } if (!strcmp(type, "database")) { @@ -2143,15 +2189,22 @@ ZOOM_API(const char *) /* from now on - we have a database record .. */ if (!strcmp(type, "render")) { - return return_record(rec, len, npr, YAZ_MARC_LINE, charset); + return get_record_format(rec, len, npr, YAZ_MARC_LINE, charset, format); } else if (!strcmp(type, "xml")) { - return return_record(rec, len, npr, YAZ_MARC_MARCXML, charset); + return get_record_format(rec, len, npr, YAZ_MARC_MARCXML, charset, + format); + } + else if (!strcmp(type, "txml")) + { + return get_record_format(rec, len, npr, YAZ_MARC_TMARCXML, charset, + format); } else if (!strcmp(type, "raw")) { - return return_record(rec, len, npr, YAZ_MARC_ISO2709, charset); + return get_record_format(rec, len, npr, YAZ_MARC_ISO2709, charset, + format); } else if (!strcmp(type, "ext")) { @@ -2161,7 +2214,8 @@ ZOOM_API(const char *) else if (!strcmp(type, "opac")) { if (npr->u.databaseRecord->which == Z_External_OPAC) - return return_record(rec, len, npr, YAZ_MARC_MARCXML, charset); + return get_record_format(rec, len, npr, YAZ_MARC_MARCXML, charset, + format); } return 0; } @@ -2206,6 +2260,9 @@ static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, rc = (ZOOM_record_cache) odr_malloc(r->odr, sizeof(*rc)); rc->rec.odr = 0; rc->rec.wrbuf = 0; +#if YAZ_HAVE_XML2 + rc->rec.xml_mem = 0; +#endif rc->elementSetName = odr_strdup_null(r->odr, elementSetName); rc->syntax = odr_strdup_null(r->odr, syntax); @@ -2908,7 +2965,7 @@ ZOOM_API(size_t) } static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos, - int *occ, + size_t *occ, const char **value_term, size_t *value_len, const char **disp_term, size_t *disp_len) { @@ -2921,7 +2978,7 @@ static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos, *disp_len = 0; *occ = 0; - if (pos >= noent || pos < 0) + if (pos >= noent) return; if (scan->scan_response) { @@ -2966,7 +3023,7 @@ static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos, ZOOM_API(const char *) ZOOM_scanset_term(ZOOM_scanset scan, size_t pos, - int *occ, int *len) + size_t *occ, size_t *len) { const char *value_term = 0; size_t value_len = 0; @@ -2982,7 +3039,7 @@ ZOOM_API(const char *) ZOOM_API(const char *) ZOOM_scanset_display_term(ZOOM_scanset scan, size_t pos, - int *occ, int *len) + size_t *occ, size_t *len) { const char *value_term = 0; size_t value_len = 0; @@ -4080,6 +4137,8 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p; ZOOM_options_set(c->options, "sru_version", sr->srw_version); + ZOOM_options_setl(c->options, "sru_extra_response_data", + sr->extraResponseData_buf, sr->extraResponseData_len); if (sr->which == Z_SRW_searchRetrieve_response) cret = handle_srw_response(c, sr->u.response); else if (sr->which == Z_SRW_scan_response) @@ -4616,6 +4675,11 @@ ZOOM_API(int) ZOOM_connection_get_timeout(ZOOM_connection c) return ZOOM_options_get_int(c->options, "timeout", 30); } +ZOOM_API(void) ZOOM_connection_close(ZOOM_connection c) +{ + do_close(c); +} + /* * Local variables: * c-basic-offset: 4