Add Q.932 to extra dist.
[obnox/wireshark/wip.git] / epan / tvbtest.c
1 /* Standalone program to test functionality of tvbuffs.
2  *
3  * tvbtest : tvbtest.o tvbuff.o except.o
4  *
5  * $Id$
6  *
7  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "tvbuff.h"
30 #include "pint.h"
31
32 gboolean failed = FALSE;
33
34 /* Tests a tvbuff against the expected pattern/length.
35  * Returns TRUE if all tests succeeed, FALSE if any test fails */
36 gboolean
37 test(tvbuff_t *tvb, gchar* name,
38                 guint8* expected_data, guint expected_length)
39 {
40         guint                   length;
41         const guint8           *cptr;
42         guint8                  *ptr;
43         volatile gboolean       ex_thrown;
44         volatile guint32        val32;
45         guint32                 expected32;
46         guint                   incr, i;
47
48         length = tvb_length(tvb);
49
50         if (length != expected_length) {
51                 printf("01: Failed TVB=%s Length of tvb=%u while expected length=%u\n",
52                                 name, length, expected_length);
53                 failed = TRUE;
54                 return FALSE;
55         }
56
57         /* Test boundary case. A BoundsError exception should be thrown. */
58         ex_thrown = FALSE;
59         TRY {
60                 cptr = tvb_get_ptr(tvb, 0, length + 1);
61         }
62         CATCH(BoundsError) {
63                 ex_thrown = TRUE;
64         }
65         CATCH(ReportedBoundsError) {
66                 printf("02: Caught wrong exception: ReportedBoundsError\n");
67         }
68         ENDTRY;
69
70         if (!ex_thrown) {
71                 printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
72                                 name, length + 1);
73                 failed = TRUE;
74                 return FALSE;
75         }
76
77         /* Test boundary case with one more byte. A ReportedBoundsError
78            exception should be thrown. */
79         ex_thrown = FALSE;
80         TRY {
81                 cptr = tvb_get_ptr(tvb, 0, length + 2);
82         }
83         CATCH(BoundsError) {
84                 printf("03: Caught wrong exception: BoundsError\n");
85         }
86         CATCH(ReportedBoundsError) {
87                 ex_thrown = TRUE;
88         }
89         ENDTRY;
90
91         if (!ex_thrown) {
92                 printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
93                                 name, length + 2);
94                 failed = TRUE;
95                 return FALSE;
96         }
97
98         /* Test boundary case. A BoundsError exception should be thrown. */
99         ex_thrown = FALSE;
100         TRY {
101                 cptr = tvb_get_ptr(tvb, -1, 2);
102         }
103         CATCH(BoundsError) {
104                 ex_thrown = TRUE;
105         }
106         CATCH(ReportedBoundsError) {
107                 printf("04: Caught wrong exception: ReportedBoundsError\n");
108         }
109         ENDTRY;
110
111         if (!ex_thrown) {
112                 printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
113                                 " offset -1\n", name);
114                 failed = TRUE;
115                 return FALSE;
116         }
117
118         /* Test boundary case. A BoundsError exception should not be thrown. */
119         ex_thrown = FALSE;
120         TRY {
121                 cptr = tvb_get_ptr(tvb, 0, 1);
122         }
123         CATCH(BoundsError) {
124                 ex_thrown = TRUE;
125         }
126         CATCH(ReportedBoundsError) {
127                 printf("05: Caught wrong exception: ReportedBoundsError\n");
128         }
129         ENDTRY;
130
131         if (ex_thrown) {
132                 printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
133                                 " offset 0\n", name);
134                 failed = TRUE;
135                 return FALSE;
136         }
137
138         /* Test boundary case. A BoundsError exception should not be thrown. */
139         ex_thrown = FALSE;
140         TRY {
141                 cptr = tvb_get_ptr(tvb, -1, 1);
142         }
143         CATCH(BoundsError) {
144                 ex_thrown = TRUE;
145         }
146         CATCH(ReportedBoundsError) {
147                 printf("06: Caught wrong exception: ReportedBoundsError\n");
148         }
149         ENDTRY;
150
151         if (ex_thrown) {
152                 printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
153                                 " offset -1\n", name);
154                 failed = TRUE;
155                 return FALSE;
156         }
157
158
159         /* Check data at boundary. An exception should not be thrown. */
160         if (length >= 4) {
161                 ex_thrown = FALSE;
162                 TRY {
163                         val32 = tvb_get_ntohl(tvb, 0);
164                 }
165                 CATCH_ALL {
166                         ex_thrown = TRUE;
167                 }
168                 ENDTRY;
169
170                 if (ex_thrown) {
171                         printf("07: Failed TVB=%s Exception when retrieving "
172                                         "guint32 from offset 0\n", name);
173                         failed = TRUE;
174                         return FALSE;
175                 }
176
177                 expected32 = pntohl(expected_data);
178                 if (val32 != expected32) {
179                         printf("08: Failed TVB=%s  guint32 @ 0 %u != expected %u\n",
180                                         name, val32, expected32);
181                         failed = TRUE;
182                         return FALSE;
183                 }
184         }
185
186         /* Check data at boundary. An exception should not be thrown. */
187         if (length >= 4) {
188                 ex_thrown = FALSE;
189                 TRY {
190                         val32 = tvb_get_ntohl(tvb, -4);
191                 }
192                 CATCH_ALL {
193                         ex_thrown = TRUE;
194                 }
195                 ENDTRY;
196
197                 if (ex_thrown) {
198                         printf("09: Failed TVB=%s Exception when retrieving "
199                                         "guint32 from offset 0\n", name);
200                         failed = TRUE;
201                         return FALSE;
202                 }
203
204                 expected32 = pntohl(&expected_data[length-4]);
205                 if (val32 != expected32) {
206                         printf("10: Failed TVB=%s guint32 @ -4 %u != expected %u\n",
207                                         name, val32, expected32);
208                         failed = TRUE;
209                         return FALSE;
210                 }
211         }
212
213         /* Sweep across data in various sized increments checking
214          * tvb_memdup() */
215         for (incr = 1; incr < length; incr++) {
216                 for (i = 0; i < length - incr; i += incr) {
217                         ptr = tvb_memdup(tvb, i, incr);
218                         if (memcmp(ptr, &expected_data[i], incr) != 0) {
219                                 printf("11: Failed TVB=%s Offset=%d Length=%d "
220                                                 "Bad memdup\n",
221                                                 name, i, incr);
222                                 failed = TRUE;
223                                 g_free(ptr);
224                                 return FALSE;
225                         }
226                         g_free(ptr);
227                 }
228         }
229
230         /* One big memdup */
231         ptr = tvb_memdup(tvb, 0, -1);
232         if (memcmp(ptr, expected_data, length) != 0) {
233                 printf("12: Failed TVB=%s Offset=0 Length=-1 "
234                                 "Bad memdup\n", name);
235                 failed = TRUE;
236                 g_free(ptr);
237                 return FALSE;
238         }
239         g_free(ptr);
240
241
242         printf("Passed TVB=%s\n", name);
243
244         return TRUE;
245 }
246
247
248
249 void
250 run_tests(void)
251 {
252         int             i, j;
253
254         tvbuff_t        *tvb_small[3];
255         tvbuff_t        *tvb_large[3];
256         tvbuff_t        *tvb_subset[6];
257         guint8          *small[3];
258         guint8          *large[3];
259         guint8          *subset[6];
260         guint           subset_length[6];
261         guint8          temp;
262 #if 0
263         guint8          *comp[6];
264         tvbuff_t        *tvb_comp[6];
265         guint           comp_length[6];
266         int             len;
267 #endif
268         
269         for (i = 0; i < 3; i++) {
270                 small[i] = g_new(guint8, 16);
271
272                 temp = 16 * i;
273                 for (j = 0; j < 16; j++) {
274                         small[i][j] = temp + j;
275                 }
276
277                 tvb_small[i] = tvb_new_real_data(small[i], 16, 17);
278         }
279
280         for (i = 0; i < 3; i++) {
281                 large[i] = g_new(guint8, 19);
282
283                 temp = 19 * i;
284                 for (j = 0; j < 19; j++) {
285                         large[i][j] = temp + j;
286                 }
287
288                 tvb_large[i] = tvb_new_real_data(large[i], 19, 20);
289         }
290
291         /* Test the TVBUFF_REAL_DATA objects. */
292         test(tvb_small[0], "Small 0", small[0], 16);
293         test(tvb_small[1], "Small 1", small[1], 16);
294         test(tvb_small[2], "Small 2", small[2], 16);
295
296         test(tvb_large[0], "Large 0", large[0], 19);
297         test(tvb_large[1], "Large 1", large[1], 19);
298         test(tvb_large[2], "Large 2", large[2], 19);
299
300         tvb_subset[0]           = tvb_new_subset(tvb_small[0], 0, 8, 9);
301         subset[0]               = &small[0][0];
302         subset_length[0]        = 8;
303
304         tvb_subset[1]           = tvb_new_subset(tvb_large[0], -10, 10, 11);
305         subset[1]               = &large[0][9];
306         subset_length[1]        = 10;
307
308         tvb_subset[2]           = tvb_new_subset(tvb_small[1], -16, -1, 17);
309         subset[2]               = &small[1][0];
310         subset_length[2]        = 16;
311
312         tvb_subset[3]           = tvb_new_subset(tvb_subset[0], 0, 3, 4);
313         subset[3]               = &small[0][0];
314         subset_length[3]        = 3;
315
316         tvb_subset[4]           = tvb_new_subset(tvb_subset[1], -5, 5, 6);
317         subset[4]               = &large[0][14];
318         subset_length[4]        = 5;
319
320         tvb_subset[5]           = tvb_new_subset(tvb_subset[2], 4, 8, 9);
321         subset[5]               = &small[1][4];
322         subset_length[5]        = 8;
323
324         /* Test the TVBUFF_SUBSET objects. */
325         test(tvb_subset[0], "Subset 0", subset[0], subset_length[0]);
326         test(tvb_subset[1], "Subset 1", subset[1], subset_length[1]);
327         test(tvb_subset[2], "Subset 2", subset[2], subset_length[2]);
328         test(tvb_subset[3], "Subset 3", subset[3], subset_length[3]);
329         test(tvb_subset[4], "Subset 4", subset[4], subset_length[4]);
330         test(tvb_subset[5], "Subset 5", subset[5], subset_length[5]);
331
332 #if 0
333         /* Composite tvbuffs don't work at the moment -- tests commented out until
334          * they do. */
335         
336         /* One Real */
337         printf("Making Composite 0\n");
338         tvb_comp[0]             = tvb_new_composite();
339         comp[0]                 = small[0];
340         comp_length[0]          = 16;
341         tvb_composite_append(tvb_comp[0], tvb_small[0]);
342         tvb_composite_finalize(tvb_comp[0]);
343
344         /* Two Reals */
345         printf("Making Composite 1\n");
346         tvb_comp[1]             = tvb_new_composite();
347         comp[1]                 = g_malloc(32);
348         comp_length[1]          = 32;
349         memcpy(comp[1], small[0], 16);
350         memcpy(&comp[1][16], small[1], 16);
351         tvb_composite_append(tvb_comp[1], tvb_small[0]);
352         tvb_composite_append(tvb_comp[1], tvb_small[1]);
353         tvb_composite_finalize(tvb_comp[1]);
354
355         /* One subset */
356         printf("Making Composite 2\n");
357         tvb_comp[2]             = tvb_new_composite();
358         comp[2]                 = subset[1];
359         comp_length[2]          = subset_length[1];
360         tvb_composite_append(tvb_comp[2], tvb_subset[1]);
361         tvb_composite_finalize(tvb_comp[2]);
362
363         /* Two subsets */
364         printf("Making Composite 3\n");
365         tvb_comp[3]             = tvb_new_composite();
366         comp[3]                 = g_malloc(13);
367         comp_length[3]          = 13;
368         memcpy(comp[3], &large[0][14], 5);
369         memcpy(&comp[3][5], &small[1][4], 8);
370         tvb_composite_append(tvb_comp[3], tvb_subset[4]);
371         tvb_composite_append(tvb_comp[3], tvb_subset[5]);
372         tvb_composite_finalize(tvb_comp[3]);
373
374         /* One real, one subset */
375         printf("Making Composite 4\n");
376         tvb_comp[4]             = tvb_new_composite();
377         comp[4]                 = g_malloc(16 + subset_length[1]);
378         comp_length[4]          = 16 + subset_length[1];
379         memcpy(comp[4], small[0], 16);
380         memcpy(&comp[4][16], subset[1], subset_length[1]);
381         tvb_composite_append(tvb_comp[4], tvb_small[0]);
382         tvb_composite_append(tvb_comp[4], tvb_subset[1]);
383         tvb_composite_finalize(tvb_comp[4]);
384
385         /* 4 composites */
386         printf("Making Composite 5\n");
387         tvb_comp[5]             = tvb_new_composite();
388         comp_length[5]          = comp_length[0] +
389                                         comp_length[1] +
390                                         comp_length[2] +
391                                         comp_length[3];
392         comp[5]                 = g_malloc(comp_length[5]);
393
394         len = 0;
395         memcpy(&comp[5][len], comp[0], comp_length[0]);
396         len += comp_length[0];
397         memcpy(&comp[5][len], comp[1], comp_length[1]);
398         len += comp_length[1];
399         memcpy(&comp[5][len], comp[2], comp_length[2]);
400         len += comp_length[2];
401         memcpy(&comp[5][len], comp[3], comp_length[3]);
402
403         tvb_composite_append(tvb_comp[5], tvb_comp[0]);
404         tvb_composite_append(tvb_comp[5], tvb_comp[1]);
405         tvb_composite_append(tvb_comp[5], tvb_comp[2]);
406         tvb_composite_append(tvb_comp[5], tvb_comp[3]);
407         tvb_composite_finalize(tvb_comp[5]);
408
409         /* Test the TVBUFF_COMPOSITE objects. */
410         test(tvb_comp[0], "Composite 0", comp[0], comp_length[0]);
411         test(tvb_comp[1], "Composite 1", comp[1], comp_length[1]);
412         test(tvb_comp[2], "Composite 2", comp[2], comp_length[2]);
413         test(tvb_comp[3], "Composite 3", comp[3], comp_length[3]);
414         test(tvb_comp[4], "Composite 4", comp[4], comp_length[4]);
415         test(tvb_comp[5], "Composite 5", comp[5], comp_length[5]);
416 #endif
417 }
418
419 int
420 main(void)
421 {
422         except_init();
423         tvbuff_init();
424         run_tests();
425         tvbuff_cleanup();
426         except_deinit();
427         exit(failed?1:0);
428 }