Happy new year
[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             close();
83             client(m_host);
84             timeout(30);
85             return;
86         }
87     }
88     close_goto_next();
89 }
90
91 void Zlint::failNotify()
92 {
93     if (m_cur_test)
94     {
95         if (m_cur_test->m_t->recv_fail(this, 1) != TEST_FINISHED)
96         {
97             close();
98             client(m_host);
99             timeout(30);
100             return;
101         }
102     }
103     close_goto_next();
104 }
105
106 void Zlint::connectNotify()
107 {
108     if (m_cur_test)
109     {
110         if (m_cur_test->m_t->init(this) != TEST_FINISHED)
111             return;
112     }
113     close_goto_next();
114 }
115
116 void Zlint::recv_GDU(Z_GDU *gdu, int len)
117 {
118     if (m_cur_test)
119     {
120         int r = m_cur_test->m_t->recv_gdu(this, gdu);
121         if (r == TEST_CONTINUE)
122             return;
123         if (r == TEST_REOPEN)
124         {
125             close();
126             client(m_host);
127             timeout(30);
128             return;
129         }
130     }
131     close_goto_next();
132 }
133
134 void Zlint::close_goto_next()
135 {
136     close();
137     if (m_cur_test)
138         m_cur_test = m_cur_test->m_next;
139     if (m_cur_test)
140         client(m_host);
141     timeout(30);
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 off = 0;
164     int i;
165     for (i = 0; i<12; i++)
166         if (ODR_MASK_GET(init->protocolVersion, no))
167         {
168             no = i+1;
169         }
170         else
171             off = 1;
172     return no;
173 }
174
175 void Zlint::add_test(Zlint_test *t)
176 {
177     Zlint_t **d = &m_tests;
178     while (*d)
179         d = &(*d)->m_next;
180     *d = new Zlint_t(t);
181     if (!m_cur_test)
182         m_cur_test = m_tests;
183 }
184
185 void Zlint::msg_check_for(const char *fmt, ...)
186 {
187     m_cur_test->m_test_ok = 0;
188     m_cur_test->m_test_number_sequence++;
189     m_cur_test->m_test_reported = 0;
190
191     va_list ap;
192     va_start(ap, fmt);
193     char buf[1024];
194     vsnprintf(buf, sizeof(buf), fmt, ap);
195     printf ("Checking %s .. ", buf);
196     va_end(ap);
197 }
198
199 void Zlint::msg_check_info(const char *fmt, ...)
200 {
201     va_list ap;
202     va_start(ap, fmt);
203     char buf[1024];
204     vsnprintf(buf, sizeof(buf), fmt, ap);
205     printf (" %s\n", buf);
206     va_end(ap);
207 }
208
209 void Zlint::msg_check_ok()
210 {
211     if (!m_cur_test->m_test_reported)
212     {
213         m_cur_test->m_test_ok = 1;
214         m_cur_test->m_test_reported = 1;
215         printf ("OK\n");
216     }
217 }
218
219 void Zlint::msg_check_fail(const char *fmt, ...)
220 {
221     if (!m_cur_test->m_test_reported)
222     {
223         m_cur_test->m_test_ok = 0;
224         m_cur_test->m_test_reported = 1;
225         printf ("Fail\n");
226     }
227     va_list ap;
228     va_start(ap, fmt);
229     char buf[1024];
230     vsnprintf(buf, sizeof(buf), fmt, ap);
231     printf (" %s\n", buf);
232     va_end(ap);
233 }
234
235 void Zlint::msg_check_notapp()
236 {
237     if (!m_cur_test->m_test_reported)
238     {
239         m_cur_test->m_test_ok = 2;
240         m_cur_test->m_test_reported = 1;
241         printf ("Unsupported\n");
242     }
243 }
244
245 void Zlint::getDatabase(char ***db, int *num)
246 {
247     *db = (char**) odr_malloc(odr_encode(), 2*sizeof(char *));
248     (*db)[0] = m_database;
249     (*db)[1] = 0;
250     *num = 1;
251 }
252
253 Zlint_t::Zlint_t(Zlint_test *t)
254 {
255     m_test_number_sequence = 0;
256     m_test_ok = 0;
257     m_test_reported = 0;
258     m_t = t;
259     m_next = 0;
260 }
261
262 Zlint_t::~Zlint_t()
263 {
264     delete m_t;
265 }
266
267 Zlint_code Zlint_test_simple::recv_fail(Zlint *z, int reason)
268 {
269     z->msg_check_fail("target closed connection");
270     return TEST_FINISHED;
271 }
272 /*
273  * Local variables:
274  * c-basic-offset: 4
275  * c-file-style: "Stroustrup"
276  * indent-tabs-mode: nil
277  * End:
278  * vim: shiftwidth=4 tabstop=8 expandtab
279  */
280