From 55ca7cdb58b098d348054917296c0fe2c9cb1580 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 30 Apr 2007 08:29:07 +0000 Subject: [PATCH] New ZOOM C option, "rpnCharset", which allows client-side conversion of terms in RPN queries. --- NEWS | 3 ++ doc/zoom.xml | 16 ++++++++++- include/yaz/Makefile.am | 4 +-- include/yaz/copy_types.h | 57 ++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 5 ++-- src/copy_types.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/zoom-c.c | 40 +++++++++++++++++++++++++-- src/zoom-p.h | 3 +- test/tst_query_charset.c | 6 +++- 9 files changed, 192 insertions(+), 10 deletions(-) create mode 100644 include/yaz/copy_types.h create mode 100644 src/copy_types.c diff --git a/NEWS b/NEWS index bd9a2f8..8bd1b25 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +New ZOOM C option, "rpnCharset", which allows client-side conversion of +terms in RPN queries. + Clean-up the CCL API. Moved some internal structures from ccl.h to private header cclp.h. Changed ccl_parser_create so that a Bibset must be supplied. Removed tokenize API from ccl.h - including ccl_parser_find. diff --git a/doc/zoom.xml b/doc/zoom.xml index 0d0bac2..593c5a1 100644 --- a/doc/zoom.xml +++ b/doc/zoom.xml @@ -20,7 +20,7 @@ ZOOM_options_set_int(opt, name, value) ZOOM_connection_scan1 (ZOOM_connection c, ZOOM_query startterm) ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn) --> - + ZOOM &zoom; is an acronym for 'Z39.50 Object-Orientation Model' and is @@ -474,6 +474,13 @@ ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn) If this option isn't set, the ZOOM module will automatically allocate a result set name. default + + rpnCharsetCharacter set for RPN terms. + If this is set, ZOOM C will assume that the ZOOM application is + running UTF-8. Terms in RPN queries are then converted to the + rpnCharset. If this is unset, ZOOM C will not assume any encoding + of RPN terms and no conversion is performed. + none @@ -913,6 +920,13 @@ ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn) scanStatusAn integer indicating the Scan Status of last scan. 0 + + rpnCharsetCharacter set for RPN terms. + If this is set, ZOOM C will assume that the ZOOM application is + running UTF-8. Terms in RPN queries are then converted to the + rpnCharset. If this is unset, ZOOM C will not assume any encoding + of RPN terms and no conversion is performed. + none diff --git a/include/yaz/Makefile.am b/include/yaz/Makefile.am index 6aea0da..4dfa8ce 100644 --- a/include/yaz/Makefile.am +++ b/include/yaz/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.45 2007-04-26 21:45:16 adam Exp $ +## $Id: Makefile.am,v 1.46 2007-04-30 08:29:07 adam Exp $ pkginclude_HEADERS= backend.h ccl.h ccl_xml.h cql.h comstack.h \ diagbib1.h diagsrw.h diagsru_update.h sortspec.h log.h logrpn.h marcdisp.h \ @@ -8,7 +8,7 @@ pkginclude_HEADERS= backend.h ccl.h ccl_xml.h cql.h comstack.h \ tcpip.h test.h timing.h unix.h tpath.h wrbuf.h xmalloc.h \ yaz-ccl.h yaz-iconv.h yaz-util.h yaz-version.h yconfig.h proto.h \ xmlquery.h libxml2_error.h xmltypes.h snprintf.h query-charset.h \ - mutex.h oid_db.h oid_util.h oid_std.h tokenizer.h \ + mutex.h oid_db.h oid_util.h oid_std.h tokenizer.h copy_types.h \ \ ill.h ill-core.h item-req.h oclc-ill-req-ext.h z-accdes1.h z-accform1.h \ z-acckrb1.h z-core.h z-date.h z-diag1.h z-espec1.h z-estask.h z-exp.h \ diff --git a/include/yaz/copy_types.h b/include/yaz/copy_types.h new file mode 100644 index 0000000..6340843 --- /dev/null +++ b/include/yaz/copy_types.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1995-2007, Index Data + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Index Data nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* $Id: copy_types.h,v 1.1 2007-04-30 08:29:07 adam Exp $ */ +/** + * \file copy_types.h + * \brief Copies various Z39.50 types + */ + +#ifndef YAZ_COPY_TYPES_H +#define YAZ_COPY_TYPES_H + +#include +#include + +YAZ_BEGIN_CDECL + +YAZ_EXPORT +Z_RPNQuery *yaz_copy_z_RPNQuery(Z_RPNQuery *q, ODR out); + +YAZ_EXPORT +Z_Query *yaz_copy_Z_Query(Z_Query *q, ODR out); + +YAZ_END_CDECL + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/Makefile.am b/src/Makefile.am index 33112c2..2857942 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## This file is part of the YAZ toolkit. ## Copyright (C) 1995-2007, Index Data, All rights reserved. -## $Id: Makefile.am,v 1.65 2007-04-26 21:45:17 adam Exp $ +## $Id: Makefile.am,v 1.66 2007-04-30 08:29:07 adam Exp $ YAZ_VERSION_INFO=3:0:0 @@ -93,7 +93,8 @@ libyaz_la_SOURCES=version.c options.c log.c \ test.c timing.c \ xmlquery.c http.c \ mime.c mime.h oid_util.c tokenizer.c \ - record_conv.c retrieval.c elementset.c snprintf.c query-charset.c + record_conv.c retrieval.c elementset.c snprintf.c query-charset.c \ + copy_types.c libyaz_la_LDFLAGS=-version-info $(YAZ_VERSION_INFO) diff --git a/src/copy_types.c b/src/copy_types.c new file mode 100644 index 0000000..c01d8e8 --- /dev/null +++ b/src/copy_types.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1995-2007, Index Data ApS + * All rights reserved. + * + * $Id: copy_types.c,v 1.1 2007-04-30 08:29:07 adam Exp $ + */ + +/** \file copy_types.c + \brief Copies various Z39.50 types + */ + +#include + +Z_RPNQuery *yaz_copy_z_RPNQuery(Z_RPNQuery *q, ODR out) +{ + Z_RPNQuery *q1 = 0; + ODR enc = odr_createmem(ODR_ENCODE); + ODR dec = odr_createmem(ODR_DECODE); + if (!z_RPNQuery(enc, &q, 0, 0)) + return 0; + else + { + int len; + char *buf = odr_getbuf(enc, &len, 0); + if (buf) + { + odr_setbuf(dec, buf, len, 0); + z_RPNQuery(dec, &q1, 0, 0); + nmem_transfer(out->mem, dec->mem); + } + } + odr_destroy(enc); + odr_destroy(dec); + return q1; +} + +Z_Query *yaz_copy_Z_Query(Z_Query *q, ODR out) +{ + Z_Query *q1 = 0; + ODR enc = odr_createmem(ODR_ENCODE); + ODR dec = odr_createmem(ODR_DECODE); + if (!z_Query(enc, &q, 0, 0)) + return 0; + else + { + int len; + char *buf = odr_getbuf(enc, &len, 0); + if (buf) + { + odr_setbuf(dec, buf, len, 0); + z_Query(dec, &q1, 0, 0); + nmem_transfer(out->mem, dec->mem); + } + } + odr_destroy(enc); + odr_destroy(dec); + return q1; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/zoom-c.c b/src/zoom-c.c index 0951589..320a925 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.126 2007-04-24 09:29:34 adam Exp $ + * $Id: zoom-c.c,v 1.127 2007-04-30 08:29:07 adam Exp $ */ /** * \file zoom-c.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include static int log_api = 0; static int log_details = 0; @@ -762,6 +764,7 @@ ZOOM_resultset ZOOM_resultset_create(void) r->next = 0; r->databaseNames = 0; r->num_databaseNames = 0; + r->rpn_iconv = 0; return r; } @@ -792,6 +795,13 @@ ZOOM_API(ZOOM_resultset) r->query = q; r->options = ZOOM_options_create_with_parent(c->options); + + { + const char *cp = ZOOM_options_get(r->options, "rpnCharset"); + if (cp) + r->rpn_iconv = yaz_iconv_open(cp, "UTF-8"); + } + start = ZOOM_options_get_int(r->options, "start", 0); count = ZOOM_options_get_int(r->options, "count", 0); @@ -817,6 +827,8 @@ ZOOM_API(ZOOM_resultset) r->next = c->resultsets; c->resultsets = r; + + if (c->host_port && c->proto == PROTO_HTTP) { if (!c->cs) @@ -963,6 +975,8 @@ static void resultset_destroy(ZOOM_resultset r) } ZOOM_query_destroy(r->query); ZOOM_options_destroy(r->options); + if (r->rpn_iconv) + yaz_iconv_close(r->rpn_iconv); odr_destroy(r->odr); xfree(r->setname); xfree(r->schema); @@ -1296,7 +1310,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c) odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName)); - version = odr_strdup(c->odr_out, "$Revision: 1.126 $"); + version = odr_strdup(c->odr_out, "$Revision: 1.127 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; ireq->implementationVersion = @@ -1547,7 +1561,13 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c) set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0); return zoom_complete; } - + if (r->query->z_query->which == Z_Query_type_1 && r->rpn_iconv) + { + search_req->query = yaz_copy_Z_Query(r->query->z_query, c->odr_out); + + yaz_query_charset_convert_rpnquery(search_req->query->u.type_1, + c->odr_out, r->rpn_iconv); + } search_req->databaseNames = r->databaseNames; search_req->num_databaseNames = r->num_databaseNames; @@ -2684,6 +2704,20 @@ ZOOM_API(ZOOM_scanset) p_query_scan(scan->odr, PROTO_Z3950, &scan->attributeSet, start); xfree(freeme); + { + const char *cp = ZOOM_options_get(scan->options, "rpnCharset"); + if (cp) + { + yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8"); + if (cd) + { + yaz_query_charset_convert_apt(scan->termListAndStartPoint, + scan->odr, cd); + } + } + } + + scan->databaseNames = set_DatabaseNames(c, c->options, &scan->num_databaseNames, scan->odr); diff --git a/src/zoom-p.h b/src/zoom-p.h index 90c7142..7371cd0 100644 --- a/src/zoom-p.h +++ b/src/zoom-p.h @@ -2,7 +2,7 @@ * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: zoom-p.h,v 1.18 2007-04-12 13:52:57 adam Exp $ + * $Id: zoom-p.h,v 1.19 2007-04-30 08:29:07 adam Exp $ */ /** * \file zoom-p.h @@ -109,6 +109,7 @@ struct ZOOM_resultset_p { ZOOM_resultset next; char **databaseNames; int num_databaseNames; + yaz_iconv_t rpn_iconv; }; struct ZOOM_record_p { diff --git a/test/tst_query_charset.c b/test/tst_query_charset.c index c597e65..439a478 100644 --- a/test/tst_query_charset.c +++ b/test/tst_query_charset.c @@ -2,13 +2,14 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: tst_query_charset.c,v 1.1 2007-04-10 14:42:31 adam Exp $ + * $Id: tst_query_charset.c,v 1.2 2007-04-30 08:29:08 adam Exp $ */ #include #include #include +#include #include #include #include @@ -42,7 +43,10 @@ enum query_charset_status t(yaz_iconv_t cd, else { WRBUF w = wrbuf_alloc(); + Z_RPNQuery *r2 = yaz_copy_z_RPNQuery(rpn, odr); + YAZ_CHECK(r2); + YAZ_CHECK(r2 != rpn); yaz_query_charset_convert_rpnquery(rpn, odr, cd); yaz_rpnquery_to_wrbuf(w, rpn); if (!expect_pqf || strcmp(expect_pqf, wrbuf_cstr(w)) == 0) -- 1.7.10.4