Use AM_LDFLAGS instead of LDFLAGS
[yazpp-moved-to-github.git] / src / yaz-z-query.cpp
1 /*
2  * Copyright (c) 1998-2003, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-z-query.cpp,v 1.15 2003-12-20 22:42:53 adam Exp $
6  */
7
8 #include <yaz++/z-query.h>
9 #include <yaz/pquery.h>
10
11 Yaz_Z_Query::Yaz_Z_Query()
12 {
13     odr_encode = odr_createmem (ODR_ENCODE);
14     odr_decode = odr_createmem (ODR_DECODE);
15     odr_print = odr_createmem (ODR_PRINT);
16 }
17
18 int Yaz_Z_Query::set_rpn (const char *rpn)
19 {
20     m_buf = 0;
21     odr_reset (odr_encode);
22     Z_Query *query = (Z_Query*) odr_malloc (odr_encode, sizeof(*query));
23     query->which = Z_Query_type_1;
24     query->u.type_1 = p_query_rpn (odr_encode, PROTO_Z3950, rpn);
25     if (!query->u.type_1)
26         return -1;
27     if (!z_Query (odr_encode, &query, 0, 0))
28         return -1;
29     // z_Query(odr_print, &query, 0, 0);
30     m_buf = odr_getbuf (odr_encode, &m_len, 0);
31     return m_len;
32 }
33
34 void Yaz_Z_Query::set_Z_Query(Z_Query *z_query)
35 {
36     m_buf = 0;
37     odr_reset (odr_encode);
38     if (!z_Query (odr_encode, &z_query, 0, 0))
39         return;
40     m_buf = odr_getbuf (odr_encode, &m_len, 0);
41 }
42
43 Yaz_Z_Query::~Yaz_Z_Query()
44 {
45     odr_destroy (odr_encode);
46     odr_destroy (odr_decode);
47     odr_destroy (odr_print);
48 }
49
50 Z_Query *Yaz_Z_Query::get_Z_Query ()
51 {
52     Z_Query *query;
53     if (!m_buf)
54         return 0;
55     odr_reset(odr_decode);
56     odr_setbuf(odr_decode, m_buf, m_len, 0);
57     if (!z_Query(odr_decode, &query, 0, 0))
58         return 0;
59     return query;
60 }
61
62 void Yaz_Z_Query::print(char *str, int len)
63 {
64     Z_Query *query;
65     *str = 0;
66     if (!m_buf)
67         return;
68     odr_setbuf (odr_decode, m_buf, m_len, 0);
69     if (!z_Query(odr_decode, &query, 0, 0))
70         return;
71     WRBUF wbuf = zquery2pquery(query);
72     if (wbuf)
73     {
74         if (wrbuf_len(wbuf) > len-1)
75         {
76             memcpy(str, wrbuf_buf(wbuf), len-1);
77             str[len-1] = '\0';
78         }
79         else
80             strcpy(str, wrbuf_buf(wbuf));
81         wrbuf_free(wbuf,1);
82     }
83     odr_reset(odr_decode);
84 }
85
86 int Yaz_Z_Query::match(Yaz_Z_Query *other)
87 {
88     if (m_len != other->m_len)
89         return 0;
90     if (!m_buf || !other->m_buf)
91         return 0;
92     if (memcmp(m_buf, other->m_buf, m_len))
93         return 0;
94     return 1;
95 }
96
97 void Yaz_Z_Query::oid2str(Odr_oid *o, WRBUF buf)
98 {
99     for (; *o >= 0; o++) {
100         char ibuf[16];
101         sprintf(ibuf, "%d", *o);
102         wrbuf_puts(buf, ibuf);
103         if (o[1] > 0)
104             wrbuf_putc(buf, '.');
105     }
106 }
107
108 void Yaz_Z_Query::pr_term(WRBUF wbuf, char *buf, int len)
109 {
110     int i;
111     wrbuf_putc(wbuf, '"');
112     for (i = 0; i<len; i++)
113     {
114         int ch = buf[i];
115         if (ch == '"')
116             wrbuf_putc(wbuf, '\\');
117         wrbuf_putc(wbuf, ch);
118     }
119     wrbuf_puts(wbuf, "\" ");
120 }
121
122 int Yaz_Z_Query::rpn2pquery(Z_RPNStructure *s, WRBUF buf)
123 {
124     if (s->which == Z_RPNStructure_simple)
125     {
126         Z_Operand *o = s->u.simple;
127         
128         if (o->which == Z_Operand_APT) 
129         {
130             Z_AttributesPlusTerm *at = s->u.simple->u.attributesPlusTerm;
131             if (at->attributes) {
132                 int i;
133                 for (i = 0; i < at->attributes->num_attributes; i++) {
134                     wrbuf_puts(buf, "@attr ");
135                     if (at->attributes->attributes[i]->attributeSet) {
136                         oid2str(at->attributes->attributes[i]->attributeSet, buf);
137                         wrbuf_putc(buf, ' ');
138                     }
139                     wrbuf_printf(buf, "%d=", *at->attributes->attributes[i]->attributeType);
140                     wrbuf_printf(buf, "%d ", *at->attributes->attributes[i]->value.numeric);
141                 }
142             }
143             if (at->term->which == Z_Term_general)
144             {
145                 pr_term(buf, (char*) at->term->u.general->buf,
146                         at->term->u.general->len);
147             }
148             else if (at->term->which == Z_Term_characterString)
149             {
150                 wrbuf_puts(buf, "@term string ");
151                 pr_term(buf, at->term->u.characterString,
152                         strlen(at->term->u.characterString));
153
154             }
155         }
156         else if (o->which == Z_Operand_resultSetId)
157         {
158             wrbuf_printf(buf, "@set %s ", o->u.resultSetId);
159         }
160     }
161     else if (s->which == Z_RPNStructure_complex)
162     {
163         Z_Complex *c = s->u.complex;
164         
165         switch (c->roperator->which) {
166         case Z_Operator_and: wrbuf_puts(buf, "@and "); break;
167         case Z_Operator_or: wrbuf_puts(buf, "@or "); break;
168         case Z_Operator_and_not: wrbuf_puts(buf, "@not "); break;
169         case Z_Operator_prox: wrbuf_puts(buf, "@prox "); break;
170         default: wrbuf_puts(buf, "@unknown ");
171         }
172         if (!rpn2pquery(c->s1, buf))
173             return 0;
174         if (!rpn2pquery(c->s2, buf))
175             return 0;
176     }
177     return 1;
178 }
179
180 WRBUF Yaz_Z_Query::zquery2pquery(Z_Query *q)
181 {
182     if (q->which != Z_Query_type_1 && q->which != Z_Query_type_101) 
183         return 0;
184     WRBUF buf = wrbuf_alloc();
185     if (q->u.type_1->attributeSetId) {
186         /* Output attribute set ID */
187         wrbuf_puts(buf, "@attrset ");
188         oid2str(q->u.type_1->attributeSetId, buf);
189         wrbuf_putc(buf, ' ');
190     }
191     return rpn2pquery(q->u.type_1->RPNStructure, buf) ? buf : 0;
192 }
193
194