Link SSL with libyaz.la and yaz-client only.
[yaz-moved-to-github.git] / src / querytowrbuf.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2008 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /** \file querytowrbuf.c
7     \brief Query to WRBUF (to strings)
8  */
9
10 #include <stdio.h>
11 #include <assert.h>
12
13 #include <yaz/logrpn.h>
14 #include <yaz/querytowrbuf.h>
15 #include <yaz/oid_db.h>
16
17 static void yaz_term_to_wrbuf(WRBUF b, const char *term, int len)
18 {
19     int i;
20     for (i = 0; i < len; i++)
21         if (strchr(" \"{", term[i]))
22             break;
23     if (i == len && i)
24         wrbuf_printf(b, "%.*s ", len, term);
25     else
26     {
27         wrbuf_putc(b, '"');
28         for (i = 0; i<len; i++)
29         {
30             if (term[i] == '"')
31                 wrbuf_putc(b, '\\');
32             wrbuf_putc(b, term[i]);
33         }
34         wrbuf_printf(b, "\" ");
35     }
36 }
37
38 static void yaz_attribute_element_to_wrbuf(WRBUF b,
39                                            const Z_AttributeElement *element)
40 {
41     int i;
42     char oid_name_str[OID_STR_MAX];
43     const char *setname = 0;
44     char *sep = " "; /* optional space after attrset name */
45     if (element->attributeSet)
46     {
47         setname = yaz_oid_to_string_buf(element->attributeSet, 
48                                         0, oid_name_str);
49     }
50     if (!setname)
51     {
52         setname = "";
53         sep = "";
54     }
55     switch (element->which) 
56     {
57     case Z_AttributeValue_numeric:
58         wrbuf_printf(b,"@attr %s%s%d=%d ", setname, sep,
59                      *element->attributeType, *element->value.numeric);
60         break;
61     case Z_AttributeValue_complex:
62         wrbuf_printf(b,"@attr %s%s\"%d=", setname, sep,
63                      *element->attributeType);
64         for (i = 0; i<element->value.complex->num_list; i++)
65         {
66             if (i)
67                 wrbuf_printf(b,",");
68             if (element->value.complex->list[i]->which ==
69                 Z_StringOrNumeric_string)
70                 wrbuf_printf (b, "%s",
71                               element->value.complex->list[i]->u.string);
72             else if (element->value.complex->list[i]->which ==
73                      Z_StringOrNumeric_numeric)
74                 wrbuf_printf (b, "%d", 
75                               *element->value.complex->list[i]->u.numeric);
76         }
77         wrbuf_printf(b, "\" ");
78         break;
79     default:
80         wrbuf_printf (b, "@attr 1=unknown ");
81     }
82 }
83
84 static const char *complex_op_name(const Z_Operator *op)
85 {
86     switch (op->which)
87     {
88     case Z_Operator_and:
89         return "and";
90     case Z_Operator_or:
91         return "or";
92     case Z_Operator_and_not:
93         return "not";
94     case Z_Operator_prox:
95         return "prox";
96     default:
97         return "unknown complex operator";
98     }
99 }
100
101 static void yaz_apt_to_wrbuf(WRBUF b, const Z_AttributesPlusTerm *zapt)
102 {
103     int num_attributes = zapt->attributes->num_attributes;
104     int i;
105     for (i = 0; i<num_attributes; i++)
106         yaz_attribute_element_to_wrbuf(b,zapt->attributes->attributes[i]);
107     
108     switch (zapt->term->which)
109     {
110     case Z_Term_general:
111         yaz_term_to_wrbuf(b, (const char *)zapt->term->u.general->buf,
112                           zapt->term->u.general->len);
113         break;
114     case Z_Term_characterString:
115         wrbuf_printf(b, "@term string ");
116         yaz_term_to_wrbuf(b, zapt->term->u.characterString,
117                           strlen(zapt->term->u.characterString));
118         break;
119     case Z_Term_numeric:
120         wrbuf_printf(b, "@term numeric %d ", *zapt->term->u.numeric);
121         break;
122     case Z_Term_null:
123         wrbuf_printf(b, "@term null x");
124         break;
125     default:
126         wrbuf_printf(b, "@term null unknown%d ", zapt->term->which);
127     }
128 }
129
130 static void yaz_rpnstructure_to_wrbuf(WRBUF b, const Z_RPNStructure *zs)
131 {
132     if (zs->which == Z_RPNStructure_complex)
133     {
134         Z_Operator *op = zs->u.complex->roperator;
135         wrbuf_printf(b, "@%s ", complex_op_name(op) );
136         if (op->which== Z_Operator_prox)
137         {
138             if (!op->u.prox->exclusion)
139                 wrbuf_putc(b, 'n');
140             else if (*op->u.prox->exclusion)
141                 wrbuf_putc(b, '1');
142             else
143                 wrbuf_putc(b, '0');
144
145             wrbuf_printf(b, " %d %d %d ", *op->u.prox->distance,
146                          *op->u.prox->ordered,
147                          *op->u.prox->relationType);
148
149             switch(op->u.prox->which)
150             {
151             case Z_ProximityOperator_known:
152                 wrbuf_putc(b, 'k');
153                 break;
154             case Z_ProximityOperator_private:
155                 wrbuf_putc(b, 'p');
156                 break;
157             default:
158                 wrbuf_printf(b, "%d", op->u.prox->which);
159             }
160             if (op->u.prox->u.known)
161                 wrbuf_printf(b, " %d ", *op->u.prox->u.known);
162             else
163                 wrbuf_printf(b, " 0 ");
164         }
165         yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s1);
166         yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s2);
167     }
168     else if (zs->which == Z_RPNStructure_simple)
169     {
170         if (zs->u.simple->which == Z_Operand_APT)
171             yaz_apt_to_wrbuf(b, zs->u.simple->u.attributesPlusTerm);
172         else if (zs->u.simple->which == Z_Operand_resultSetId)
173         {
174             wrbuf_printf(b, "@set ");
175             yaz_term_to_wrbuf(b, zs->u.simple->u.resultSetId,
176                               strlen(zs->u.simple->u.resultSetId));
177         }
178         else
179             wrbuf_printf (b, "(unknown simple structure)");
180     }
181     else
182         wrbuf_puts(b, "(unknown structure)");
183 }
184
185 void yaz_rpnquery_to_wrbuf(WRBUF b, const Z_RPNQuery *rpn)
186 {
187     if (rpn->attributeSetId)
188     {
189         char oid_name_str[OID_STR_MAX];
190         const char *oid_name = yaz_oid_to_string_buf(rpn->attributeSetId,
191                                                      0, oid_name_str);
192         if (oid_name)
193             wrbuf_printf(b, "@attrset %s ", oid_name);
194     } 
195     yaz_rpnstructure_to_wrbuf(b, rpn->RPNStructure);
196     wrbuf_chop_right(b);
197 }
198
199 void yaz_query_to_wrbuf(WRBUF b, const Z_Query *q)
200 {
201     assert(q);
202     assert(b);
203     switch (q->which)
204     {
205     case Z_Query_type_1: 
206     case Z_Query_type_101:
207         wrbuf_printf(b,"RPN ");
208         yaz_rpnquery_to_wrbuf(b, q->u.type_1);
209         break;
210     case Z_Query_type_2:
211         wrbuf_printf(b, "CCL %.*s", q->u.type_2->len, q->u.type_2->buf);
212         break;
213     case Z_Query_type_100:
214         wrbuf_printf(b, "Z39.58 %.*s", q->u.type_100->len,
215                      q->u.type_100->buf);
216         break;
217     case Z_Query_type_104:
218         if (q->u.type_104->which == Z_External_CQL)
219             wrbuf_printf(b, "CQL %s", q->u.type_104->u.cql);
220         else
221             wrbuf_printf(b,"UNKNOWN type 104 query %d", q->u.type_104->which);
222     }
223 }
224
225 void yaz_scan_to_wrbuf(WRBUF b, const Z_AttributesPlusTerm *zapt,
226                        const Odr_oid *attrbute_set)
227 {
228     /* should print attr set here */
229     wrbuf_printf(b, "RPN ");
230     yaz_apt_to_wrbuf(b, zapt);
231 }
232
233 void wrbuf_diags(WRBUF b, int num_diagnostics,Z_DiagRec **diags)
234 {
235     /* we only dump the first diag - that keeps the log cleaner. */
236     wrbuf_printf(b," ERROR ");
237     if (diags[0]->which != Z_DiagRec_defaultFormat)
238         wrbuf_printf(b,"(diag not in default format?)");
239     else
240     {
241         Z_DefaultDiagFormat *e=diags[0]->u.defaultFormat;
242         if (e->condition)
243             wrbuf_printf(b, "%d ",*e->condition);
244         else
245             wrbuf_printf(b, "?? ");
246         if ((e->which==Z_DefaultDiagFormat_v2Addinfo) && (e->u.v2Addinfo))
247             wrbuf_printf(b,"%s ",e->u.v2Addinfo);
248         else if ((e->which==Z_DefaultDiagFormat_v3Addinfo) && (e->u.v3Addinfo))
249             wrbuf_printf(b,"%s ",e->u.v3Addinfo);
250     }
251 }
252
253 /*
254  * Local variables:
255  * c-basic-offset: 4
256  * indent-tabs-mode: nil
257  * End:
258  * vim: shiftwidth=4 tabstop=8 expandtab
259  */
260