1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2013 Index Data
3 * See the file LICENSE for details.
5 /** \file querytowrbuf.c
6 \brief Convert Z39.50 Z_Query to PQF (as WRBUF string)
15 #include <yaz/logrpn.h>
16 #include <yaz/querytowrbuf.h>
17 #include <yaz/oid_db.h>
19 void yaz_encode_pqf_term(WRBUF b, const char *term, int len)
22 for (i = 0; i < len; i++)
23 if (strchr(" \"{", term[i]))
25 if (len > 0 && i == len)
29 for (i = 0; i < len; i++)
33 wrbuf_putc(b, term[i]);
39 for (i = 0; i < len; i++)
41 if (term[i] == '"' || term[i] == '\\')
43 wrbuf_putc(b, term[i]);
50 static void yaz_attribute_element_to_wrbuf(WRBUF b,
51 const Z_AttributeElement *element)
55 wrbuf_puts(b, "@attr ");
56 if (element->attributeSet)
58 char oid_name_str[OID_STR_MAX];
59 const char *setname = yaz_oid_to_string_buf(element->attributeSet,
63 wrbuf_puts(b, setname);
67 wrbuf_printf(b, ODR_INT_PRINTF "=", *element->attributeType);
68 switch (element->which)
70 case Z_AttributeValue_numeric:
71 wrbuf_printf(b, ODR_INT_PRINTF, *element->value.numeric);
73 case Z_AttributeValue_complex:
74 for (i = 0; i < element->value.complex->num_list; i++)
78 if (element->value.complex->list[i]->which ==
79 Z_StringOrNumeric_string)
80 wrbuf_puts(b, element->value.complex->list[i]->u.string);
81 else if (element->value.complex->list[i]->which ==
82 Z_StringOrNumeric_numeric)
83 wrbuf_printf(b, ODR_INT_PRINTF,
84 *element->value.complex->list[i]->u.numeric);
88 wrbuf_puts(b, "@attr 1=unknown");
93 static const char *complex_op_name(const Z_Operator *op)
101 case Z_Operator_and_not:
103 case Z_Operator_prox:
106 return "unknown complex operator";
110 static void yaz_apt_to_wrbuf(WRBUF b, const Z_AttributesPlusTerm *zapt)
112 int num_attributes = zapt->attributes->num_attributes;
114 for (i = 0; i < num_attributes; i++)
115 yaz_attribute_element_to_wrbuf(b,zapt->attributes->attributes[i]);
117 switch (zapt->term->which)
120 yaz_encode_pqf_term(b, (const char *)zapt->term->u.general->buf,
121 zapt->term->u.general->len);
123 case Z_Term_characterString:
124 wrbuf_puts(b, "@term string ");
125 yaz_encode_pqf_term(b, zapt->term->u.characterString,
126 strlen(zapt->term->u.characterString));
129 wrbuf_printf(b, "@term numeric " ODR_INT_PRINTF " ",
130 *zapt->term->u.numeric);
133 wrbuf_puts(b, "@term null x");
136 wrbuf_printf(b, "@term null unknown%d ", zapt->term->which);
140 static void yaz_rpnstructure_to_wrbuf(WRBUF b, const Z_RPNStructure *zs)
142 if (zs->which == Z_RPNStructure_complex)
144 Z_Operator *op = zs->u.complex->roperator;
145 wrbuf_printf(b, "@%s ", complex_op_name(op) );
146 if (op->which== Z_Operator_prox)
148 if (!op->u.prox->exclusion)
150 else if (*op->u.prox->exclusion)
155 wrbuf_printf(b, " " ODR_INT_PRINTF " %d "
156 ODR_INT_PRINTF " ", *op->u.prox->distance,
157 *op->u.prox->ordered,
158 *op->u.prox->relationType);
160 switch(op->u.prox->which)
162 case Z_ProximityOperator_known:
165 case Z_ProximityOperator_private:
169 wrbuf_printf(b, "%d", op->u.prox->which);
171 if (op->u.prox->u.known)
172 wrbuf_printf(b, " " ODR_INT_PRINTF " ", *op->u.prox->u.known);
174 wrbuf_printf(b, " 0 ");
176 yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s1);
177 yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s2);
179 else if (zs->which == Z_RPNStructure_simple)
181 if (zs->u.simple->which == Z_Operand_APT)
182 yaz_apt_to_wrbuf(b, zs->u.simple->u.attributesPlusTerm);
183 else if (zs->u.simple->which == Z_Operand_resultSetId)
185 wrbuf_printf(b, "@set ");
186 yaz_encode_pqf_term(b, zs->u.simple->u.resultSetId,
187 strlen(zs->u.simple->u.resultSetId));
190 wrbuf_puts(b, "(unknown simple structure)");
193 wrbuf_puts(b, "(unknown structure)");
196 void yaz_rpnquery_to_wrbuf(WRBUF b, const Z_RPNQuery *rpn)
198 if (rpn->attributeSetId)
200 char oid_name_str[OID_STR_MAX];
201 const char *oid_name = yaz_oid_to_string_buf(rpn->attributeSetId,
204 wrbuf_printf(b, "@attrset %s ", oid_name);
206 yaz_rpnstructure_to_wrbuf(b, rpn->RPNStructure);
210 void yaz_query_to_wrbuf(WRBUF b, const Z_Query *q)
217 case Z_Query_type_101:
218 wrbuf_puts(b,"RPN ");
219 yaz_rpnquery_to_wrbuf(b, q->u.type_1);
222 wrbuf_puts(b, "CCL ");
223 wrbuf_write(b, (const char *) q->u.type_2->buf, q->u.type_2->len);
225 case Z_Query_type_100:
226 wrbuf_puts(b, "Z39.58 ");
227 wrbuf_write(b, (const char *) q->u.type_100->buf, q->u.type_100->len);
229 case Z_Query_type_104:
230 if (q->u.type_104->which == Z_External_CQL)
232 wrbuf_puts(b, "CQL ");
233 wrbuf_puts(b, q->u.type_104->u.cql);
236 wrbuf_printf(b,"UNKNOWN type 104 query %d", q->u.type_104->which);
240 void yaz_scan_to_wrbuf(WRBUF b, const Z_AttributesPlusTerm *zapt,
241 const Odr_oid *attrbute_set)
243 /* should print attr set here */
244 wrbuf_puts(b, "RPN ");
245 yaz_apt_to_wrbuf(b, zapt);
248 void wrbuf_diags(WRBUF b, int num_diagnostics, Z_DiagRec **diags)
250 /* we only dump the first diag - that keeps the log cleaner. */
251 wrbuf_puts(b," ERROR ");
252 if (diags[0]->which != Z_DiagRec_defaultFormat)
253 wrbuf_puts(b,"(diag not in default format?)");
256 Z_DefaultDiagFormat *e = diags[0]->u.defaultFormat;
258 wrbuf_printf(b, ODR_INT_PRINTF " ",*e->condition);
260 wrbuf_puts(b, "?? ");
261 if ((e->which==Z_DefaultDiagFormat_v2Addinfo) && (e->u.v2Addinfo))
262 wrbuf_puts(b, e->u.v2Addinfo);
263 else if ((e->which==Z_DefaultDiagFormat_v3Addinfo) && (e->u.v3Addinfo))
264 wrbuf_puts(b, e->u.v3Addinfo);
272 * c-file-style: "Stroustrup"
273 * indent-tabs-mode: nil
275 * vim: shiftwidth=4 tabstop=8 expandtab