Happy new year
[yazpp-moved-to-github.git] / zlint / zlint.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) 1998-2009 Index Data and Mike Taylor
3  * See the file LICENSE for details.
4  */
5
6 #include <stdio.h>
7 #include <stdarg.h>
8
9 #include <yaz/comstack.h>
10 #include <yaz/options.h>
11 #include <yaz/otherinfo.h>
12 #include <yaz/charneg.h>
13 #include <yaz/log.h>
14
15 #include <zlint.h>
16
17 Zlint_test::~Zlint_test()
18 {
19
20 }
21
22 class Zlint_t {
23 public:
24     friend class Zlint;
25     Zlint_t(Zlint_test *t);
26     ~Zlint_t();
27 private:
28     Zlint_test *m_t;
29     Zlint_t *m_next;
30     int m_test_number_sequence;
31     int m_test_ok;
32     int m_test_reported;
33 };
34
35 Zlint::Zlint(IPDU_Observable *the_PDU_Observable) : 
36     Z_Assoc(the_PDU_Observable)
37     
38 {
39     m_PDU_Observable = the_PDU_Observable;
40     m_host = 0;
41     m_tests = 0;
42     m_cur_test = 0;
43     m_database = 0;
44 }
45
46 Zlint::~Zlint()
47 {
48     while (m_tests)
49     {
50         Zlint_t *t = m_tests;
51         m_tests = t->m_next;
52         delete t;
53     }
54     xfree(m_host);
55     xfree(m_database);
56 }
57
58 void Zlint::set_host(const char *cp)
59 {
60     xfree(m_host);
61     m_host = xstrdup(cp);
62     client(m_host);
63     timeout(30);
64
65     const char *basep;
66     cs_get_host_args(m_host, &basep);
67     if (!basep || !*basep)
68         basep = "Default";
69     xfree(m_database);
70     m_database = xstrdup(basep);
71 }
72
73 void Zlint::timeoutNotify()
74 {
75     if (m_cur_test)
76     {
77         if (m_cur_test->m_t->recv_fail(this, 2) != TEST_FINISHED)
78         {
79             close();
80             client(m_host);
81             timeout(30);
82             return;
83         }
84     }
85     close_goto_next();
86 }
87
88 void Zlint::failNotify()
89 {
90     if (m_cur_test)
91     {
92         if (m_cur_test->m_t->recv_fail(this, 1) != TEST_FINISHED)
93         {
94             close();
95             client(m_host);
96             timeout(30);
97             return;
98         }
99     }
100     close_goto_next();
101 }
102
103 void Zlint::connectNotify()
104 {
105     if (m_cur_test)
106     {
107         if (m_cur_test->m_t->init(this) != TEST_FINISHED)
108             return;
109     }
110     close_goto_next();
111 }
112
113 void Zlint::recv_GDU(Z_GDU *gdu, int len)
114 {
115     if (m_cur_test)
116     {
117         int r = m_cur_test->m_t->recv_gdu(this, gdu);
118         if (r == TEST_CONTINUE)
119             return;
120         if (r == TEST_REOPEN)
121         {
122             close();
123             client(m_host);
124             timeout(30);
125             return;
126         }
127     }
128     close_goto_next();
129 }
130
131 void Zlint::close_goto_next()
132 {
133     close();
134     if (m_cur_test)
135         m_cur_test = m_cur_test->m_next;
136     if (m_cur_test)
137         client(m_host);
138     timeout(30);
139 }
140
141 IPDU_Observer *Zlint::sessionNotify(
142     IPDU_Observable *the_PDU_Observable, int fd)
143 {
144     return 0;
145 }
146
147 Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
148 {
149     Z_ReferenceId *id = 
150         (Z_ReferenceId *) odr_malloc(odr_encode(), sizeof(*id));
151     id->size = id->len = len;
152     id->buf = (unsigned char*) odr_malloc(odr_encode(), len);
153     memcpy(id->buf, buf, len);
154     return id;
155 }
156
157 int Zlint::initResponseGetVersion(Z_InitResponse *init)
158 {
159     int no = 0;
160     int off = 0;
161     int i;
162     for (i = 0; i<12; i++)
163         if (ODR_MASK_GET(init->protocolVersion, no))
164         {
165             no = i+1;
166         }
167         else
168             off = 1;
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  * indent-tabs-mode: nil
273  * End:
274  * vim: shiftwidth=4 tabstop=8 expandtab
275  */
276