Happy new year
[yazpp-moved-to-github.git] / src / yaz-z-query.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) Index Data and Mike Taylor
3  * See the file LICENSE for details.
4  */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 #include <yaz/querytowrbuf.h>
10 #include <yazpp/z-query.h>
11 #include <yaz/pquery.h>
12 #include <assert.h>
13
14 using namespace yazpp_1;
15
16 class Yaz_Z_Query::Rep {
17     friend class Yaz_Z_Query;
18     char *buf;
19     int len;
20     ODR odr_decode;
21     ODR odr_encode;
22     ODR odr_print;
23 };
24
25
26 Yaz_Z_Query::Yaz_Z_Query()
27 {
28     m_p = new Rep;
29     m_p->odr_encode = odr_createmem(ODR_ENCODE);
30     m_p->odr_decode = odr_createmem(ODR_DECODE);
31     m_p->odr_print = odr_createmem(ODR_PRINT);
32     m_p->len = 0;
33     m_p->buf = 0;
34 }
35
36
37 Yaz_Z_Query::Yaz_Z_Query(const Yaz_Z_Query &q)
38 {
39     m_p = new Rep;
40
41     m_p->odr_encode = odr_createmem(ODR_ENCODE);
42     m_p->odr_decode = odr_createmem(ODR_DECODE);
43     m_p->odr_print = odr_createmem(ODR_PRINT);
44
45     m_p->len = q.m_p->len;
46     m_p->buf = (char*) odr_malloc(m_p->odr_encode, m_p->len);
47     memcpy(m_p->buf, q.m_p->buf, m_p->len);
48 }
49
50 Yaz_Z_Query& Yaz_Z_Query::operator=(const Yaz_Z_Query &q)
51 {
52     if (this != &q)
53     {
54         odr_reset(m_p->odr_encode);
55         if (!q.m_p->buf)
56         {
57             m_p->buf = 0;
58             m_p->len = 0;
59         }
60         else
61         {
62             m_p->len = q.m_p->len;
63             m_p->buf = (char*) odr_malloc(m_p->odr_encode, m_p->len);
64             memcpy(m_p->buf, q.m_p->buf, m_p->len);
65         }
66     }
67     return *this;
68 }
69
70 Yaz_Z_Query& Yaz_Z_Query::operator=(const char *rpn)
71 {
72     set_rpn(rpn);
73     return *this;
74 }
75
76 int Yaz_Z_Query::set_rpn(const char *rpn)
77 {
78     m_p->buf = 0;
79     odr_reset(m_p->odr_encode);
80     Z_Query *query = (Z_Query*) odr_malloc(m_p->odr_encode, sizeof(*query));
81     query->which = Z_Query_type_1;
82     query->u.type_1 = p_query_rpn(m_p->odr_encode, rpn);
83     if (!query->u.type_1)
84         return -1;
85     if (!z_Query(m_p->odr_encode, &query, 0, 0))
86         return -1;
87     m_p->buf = odr_getbuf(m_p->odr_encode, &m_p->len, 0);
88     return m_p->len;
89 }
90
91 void Yaz_Z_Query::set_Z_Query(Z_Query *z_query)
92 {
93     m_p->buf = 0;
94     odr_reset(m_p->odr_encode);
95     if (!z_Query(m_p->odr_encode, &z_query, 0, 0))
96         return;
97     m_p->buf = odr_getbuf(m_p->odr_encode, &m_p->len, 0);
98 }
99
100 Yaz_Z_Query::~Yaz_Z_Query()
101 {
102     odr_destroy(m_p->odr_encode);
103     odr_destroy(m_p->odr_decode);
104     odr_destroy(m_p->odr_print);
105     delete m_p;
106 }
107
108 Z_Query *Yaz_Z_Query::get_Z_Query()
109 {
110     Z_Query *query;
111     if (!m_p->buf)
112         return 0;
113     odr_reset(m_p->odr_decode);
114     odr_setbuf(m_p->odr_decode, m_p->buf, m_p->len, 0);
115     if (!z_Query(m_p->odr_decode, &query, 0, 0))
116         return 0;
117     return query;
118 }
119
120 void Yaz_Z_Query::print(char *str, size_t len)
121 {
122     Z_Query *query;
123     *str = 0;
124     if (!m_p->buf)
125         return;
126     odr_setbuf(m_p->odr_decode, m_p->buf, m_p->len, 0);
127     if (!z_Query(m_p->odr_decode, &query, 0, 0))
128         return;
129     WRBUF wbuf = wrbuf_alloc();
130     yaz_query_to_wrbuf(wbuf, query);
131     if (wrbuf_len(wbuf) > len-1)
132     {
133         memcpy(str, wrbuf_buf(wbuf), len-1);
134         str[len-1] = '\0';
135     }
136     else
137         strcpy(str, wrbuf_cstr(wbuf));
138     wrbuf_destroy(wbuf);
139     odr_reset(m_p->odr_decode);
140 }
141
142 int Yaz_Z_Query::match(const Yaz_Z_Query *other)
143 {
144     if (m_p->len != other->m_p->len)
145         return 0;
146     if (!m_p->buf || !other->m_p->buf)
147         return 0;
148     if (memcmp(m_p->buf, other->m_p->buf, m_p->len))
149         return 0;
150     return 1;
151 }
152
153 /*
154  * Local variables:
155  * c-basic-offset: 4
156  * c-file-style: "Stroustrup"
157  * indent-tabs-mode: nil
158  * End:
159  * vim: shiftwidth=4 tabstop=8 expandtab
160  */
161