Update zlint for new z-assoc/pdu-assoc behavior
[yazpp-moved-to-github.git] / zlint / zlint.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) 1998-2012 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 <stdio.h>
10 #include <stdarg.h>
11
12 #include <yaz/comstack.h>
13 #include <yaz/options.h>
14 #include <yaz/otherinfo.h>
15 #include <yaz/charneg.h>
16 #include <yaz/log.h>
17
18 #include <zlint.h>
19
20 Zlint_test::~Zlint_test()
21 {
22
23 }
24
25 class Zlint_t {
26 public:
27     friend class Zlint;
28     Zlint_t(Zlint_test *t);
29     ~Zlint_t();
30 private:
31     Zlint_test *m_t;
32     Zlint_t *m_next;
33     int m_test_number_sequence;
34     int m_test_ok;
35     int m_test_reported;
36 };
37
38 Zlint::Zlint(IPDU_Observable *the_PDU_Observable) :
39     Z_Assoc(the_PDU_Observable)
40
41 {
42     m_PDU_Observable = the_PDU_Observable;
43     m_host = 0;
44     m_tests = 0;
45     m_cur_test = 0;
46     m_database = 0;
47 }
48
49 Zlint::~Zlint()
50 {
51     while (m_tests)
52     {
53         Zlint_t *t = m_tests;
54         m_tests = t->m_next;
55         delete t;
56     }
57     xfree(m_host);
58     xfree(m_database);
59 }
60
61 void Zlint::set_host(const char *cp)
62 {
63     xfree(m_host);
64     m_host = xstrdup(cp);
65     client(m_host);
66     timeout(30);
67
68     const char *basep;
69     cs_get_host_args(m_host, &basep);
70     if (!basep || !*basep)
71         basep = "Default";
72     xfree(m_database);
73     m_database = xstrdup(basep);
74 }
75
76 void Zlint::timeoutNotify()
77 {
78     if (m_cur_test)
79     {
80         if (m_cur_test->m_t->recv_fail(this, 2) != TEST_FINISHED)
81         {
82             client(m_host);
83             timeout(30);
84             return;
85         }
86         close_goto_next();
87     }
88 }
89
90 void Zlint::failNotify()
91 {
92     if (m_cur_test)
93     {
94         if (m_cur_test->m_t->recv_fail(this, 1) != TEST_FINISHED)
95         {
96             client(m_host);
97             timeout(30);
98             return;
99         }
100         close_goto_next();
101     }
102 }
103
104 void Zlint::connectNotify()
105 {
106     if (m_cur_test)
107     {
108         if (m_cur_test->m_t->init(this) != TEST_FINISHED)
109             return;
110         close_goto_next();
111     }
112 }
113
114 void Zlint::recv_GDU(Z_GDU *gdu, int len)
115 {
116     if (m_cur_test)
117     {
118         int r = m_cur_test->m_t->recv_gdu(this, gdu);
119         if (r == TEST_CONTINUE)
120             return;
121         if (r == TEST_REOPEN)
122         {
123             client(m_host);
124             timeout(30);
125             return;
126         }
127         close_goto_next();
128     }
129 }
130
131 void Zlint::close_goto_next()
132 {
133     if (m_cur_test)
134         m_cur_test = m_cur_test->m_next;
135     if (m_cur_test)
136     {
137         client(m_host);
138         timeout(30);
139     }
140     else
141         close();
142 }
143
144 IPDU_Observer *Zlint::sessionNotify(
145     IPDU_Observable *the_PDU_Observable, int fd)
146 {
147     return 0;
148 }
149
150 Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
151 {
152     Z_ReferenceId *id =
153         (Z_ReferenceId *) odr_malloc(odr_encode(), sizeof(*id));
154     id->size = id->len = len;
155     id->buf = (unsigned char*) odr_malloc(odr_encode(), len);
156     memcpy(id->buf, buf, len);
157     return id;
158 }
159
160 int Zlint::initResponseGetVersion(Z_InitResponse *init)
161 {
162     int no = 0;
163     int i;
164     for (i = 0; i<12; i++)
165         if (ODR_MASK_GET(init->protocolVersion, no))
166         {
167             no = i+1;
168         }
169     return no;
170 }
171
172 void Zlint::add_test(Zlint_test *t)
173 {
174     Zlint_t **d = &m_tests;
175     while (*d)
176         d = &(*d)->m_next;
177     *d = new Zlint_t(t);
178     if (!m_cur_test)
179         m_cur_test = m_tests;
180 }
181
182 void Zlint::msg_check_for(const char *fmt, ...)
183 {
184     m_cur_test->m_test_ok = 0;
185     m_cur_test->m_test_number_sequence++;
186     m_cur_test->m_test_reported = 0;
187
188     va_list ap;
189     va_start(ap, fmt);
190     char buf[1024];
191     vsnprintf(buf, sizeof(buf), fmt, ap);
192     printf ("Checking %s .. ", buf);
193     va_end(ap);
194 }
195
196 void Zlint::msg_check_info(const char *fmt, ...)
197 {
198     va_list ap;
199     va_start(ap, fmt);
200     char buf[1024];
201     vsnprintf(buf, sizeof(buf), fmt, ap);
202     printf (" %s\n", buf);
203     va_end(ap);
204 }
205
206 void Zlint::msg_check_ok()
207 {
208     if (!m_cur_test->m_test_reported)
209     {
210         m_cur_test->m_test_ok = 1;
211         m_cur_test->m_test_reported = 1;
212         printf ("OK\n");
213     }
214 }
215
216 void Zlint::msg_check_fail(const char *fmt, ...)
217 {
218     if (!m_cur_test->m_test_reported)
219     {
220         m_cur_test->m_test_ok = 0;
221         m_cur_test->m_test_reported = 1;
222         printf ("Fail\n");
223     }
224     va_list ap;
225     va_start(ap, fmt);
226     char buf[1024];
227     vsnprintf(buf, sizeof(buf), fmt, ap);
228     printf (" %s\n", buf);
229     va_end(ap);
230 }
231
232 void Zlint::msg_check_notapp()
233 {
234     if (!m_cur_test->m_test_reported)
235     {
236         m_cur_test->m_test_ok = 2;
237         m_cur_test->m_test_reported = 1;
238         printf ("Unsupported\n");
239     }
240 }
241
242 void Zlint::getDatabase(char ***db, int *num)
243 {
244     *db = (char**) odr_malloc(odr_encode(), 2*sizeof(char *));
245     (*db)[0] = m_database;
246     (*db)[1] = 0;
247     *num = 1;
248 }
249
250 Zlint_t::Zlint_t(Zlint_test *t)
251 {
252     m_test_number_sequence = 0;
253     m_test_ok = 0;
254     m_test_reported = 0;
255     m_t = t;
256     m_next = 0;
257 }
258
259 Zlint_t::~Zlint_t()
260 {
261     delete m_t;
262 }
263
264 Zlint_code Zlint_test_simple::recv_fail(Zlint *z, int reason)
265 {
266     z->msg_check_fail("target closed connection");
267     return TEST_FINISHED;
268 }
269 /*
270  * Local variables:
271  * c-basic-offset: 4
272  * c-file-style: "Stroustrup"
273  * indent-tabs-mode: nil
274  * End:
275  * vim: shiftwidth=4 tabstop=8 expandtab
276  */
277