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