Add tvbuff class.
[metze/wireshark/wip.git] / tvbtest.c
1 /* Standalone program to test functionality of tvbuffs.
2  *
3  * tvbtest : tvbtest.o tvbuff.o except.o
4  *
5  * $Id: tvbtest.c,v 1.1 2000/05/11 08:16:00 gram Exp $
6  *
7  * Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
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
31 #define pntohs(p)  ((guint16)                       \
32                     ((guint16)*((guint8 *)p+0)<<8|  \
33                      (guint16)*((guint8 *)p+1)<<0))
34
35 #define pntohl(p)  ((guint32)*((guint8 *)p+0)<<24|  \
36                     (guint32)*((guint8 *)p+1)<<16|  \
37                     (guint32)*((guint8 *)p+2)<<8|   \
38                     (guint32)*((guint8 *)p+3)<<0)
39
40 #define pletohs(p) ((guint16)                       \
41                     ((guint16)*((guint8 *)p+1)<<8|  \
42                      (guint16)*((guint8 *)p+0)<<0))
43
44 #define pletohl(p) ((guint32)*((guint8 *)p+3)<<24|  \
45                     (guint32)*((guint8 *)p+2)<<16|  \
46                     (guint32)*((guint8 *)p+1)<<8|   \
47                     (guint32)*((guint8 *)p+0)<<0)
48
49 /* Tests a tvbuff against the expected pattern/length.
50  * Returns TRUE if all tests succeeed, FALSE if any test fails */
51 gboolean
52 test(tvbuff_t *tvb, gchar* name,
53                 guint8* expected_data, guint expected_length)
54 {
55         guint           length;
56         guint8          *ptr;
57         gboolean        ex_thrown;
58         guint32         val32, expected32;
59         int             incr, i;
60
61         length = tvb_length(tvb);
62
63         if (length != expected_length) {
64                 printf("Failed TVB=%s Length of tvb=%u while expected length=%u\n",
65                                 name, length, expected_length);
66                 return FALSE;
67         }
68
69         /* Test boundary case. A BoundsError exception should be thrown. */
70         ex_thrown = FALSE;
71         TRY {
72                 ptr = tvb_get_ptr(tvb, 0, length + 1);
73         }
74         CATCH(BoundsError) {
75                 ex_thrown = TRUE;
76         }
77         ENDTRY;
78
79         if (!ex_thrown) {
80                 printf("Failed TVB=%s No BoundsError when retrieving %u bytes\n",
81                                 name, length + 1);
82                 return FALSE;
83         }
84
85         /* Test boundary case. A BoundsError exception should be thrown. */
86         ex_thrown = FALSE;
87         TRY {
88                 ptr = tvb_get_ptr(tvb, -1, 2);
89         }
90         CATCH(BoundsError) {
91                 ex_thrown = TRUE;
92         }
93         ENDTRY;
94
95         if (!ex_thrown) {
96                 printf("Failed TVB=%s No BoundsError when retrieving 2 bytes from"
97                                 " offset -1\n", name);
98                 return FALSE;
99         }
100
101         /* Test boundary case. A BoundsError exception should not be thrown. */
102         ex_thrown = FALSE;
103         TRY {
104                 ptr = tvb_get_ptr(tvb, 0, 1);
105         }
106         CATCH(BoundsError) {
107                 ex_thrown = TRUE;
108         }
109         ENDTRY;
110
111         if (ex_thrown) {
112                 printf("Failed TVB=%s BoundsError when retrieving 1 bytes from"
113                                 " offset 0\n", name);
114                 return FALSE;
115         }
116
117         /* Test boundary case. A BoundsError exception should not be thrown. */
118         ex_thrown = FALSE;
119         TRY {
120                 ptr = tvb_get_ptr(tvb, -1, 1);
121         }
122         CATCH(BoundsError) {
123                 ex_thrown = TRUE;
124         }
125         ENDTRY;
126
127         if (ex_thrown) {
128                 printf("Failed TVB=%s BoundsError when retrieving 1 bytes from"
129                                 " offset -1\n", name);
130                 return FALSE;
131         }
132
133
134         /* Check data at boundary. An exception should not be thrown. */
135         if (length >= 4) {
136                 ex_thrown = FALSE;
137                 TRY {
138                         val32 = tvb_get_ntohl(tvb, 0);
139                 }
140                 CATCH(BoundsError) {
141                         ex_thrown = TRUE;
142                 }
143                 ENDTRY;
144
145                 if (ex_thrown) {
146                         printf("Failed TVB=%s BoundsError when retrieving "
147                                         "guint32 from offset 0\n", name);
148                         return FALSE;
149                 }
150
151                 expected32 = pntohl(expected_data);
152                 if (val32 != expected32) {
153                         printf("Failed TVB=%s  guint32 @ 0 %u != expected %u\n",
154                                         name, val32, expected32);
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, -4);
164                 }
165                 CATCH(BoundsError) {
166                         ex_thrown = TRUE;
167                 }
168                 ENDTRY;
169
170                 if (ex_thrown) {
171                         printf("Failed TVB=%s BoundsError when retrieving "
172                                         "guint32 from offset 0\n", name);
173                         return FALSE;
174                 }
175
176                 expected32 = pntohl(&expected_data[length-4]);
177                 if (val32 != expected32) {
178                         printf("Failed TVB=%s guint32 @ -4 %u != expected %u\n",
179                                         name, val32, expected32);
180                         return FALSE;
181                 }
182         }
183
184         /* Sweep across data in various sized increments checking
185          * tvb_memdup() */
186         for (incr = 1; incr < length; incr++) {
187                 for (i = 0; i < length - incr; i += incr) {
188                         ptr = tvb_memdup(tvb, i, incr);
189                         if (memcmp(ptr, &expected_data[i], incr) != 0) {
190                                 printf("Failed TVB=%s Offset=%d Length=%d "
191                                                 "Bad memdup\n",
192                                                 name, i, incr);
193                                 g_free(ptr);
194                                 return FALSE;
195                         }
196                         g_free(ptr);
197                 }
198         }
199
200         /* One big memdup */
201         ptr = tvb_memdup(tvb, 0, -1);
202         if (memcmp(ptr, expected_data, length) != 0) {
203                 printf("Failed TVB=%s Offset=0 Length=-1 "
204                                 "Bad memdup\n", name);
205                 g_free(ptr);
206                 return FALSE;
207         }
208         g_free(ptr);
209
210
211         printf("Passed TVB=%s\n", name);
212
213         return TRUE;
214 }
215
216
217
218 void
219 run_tests(void)
220 {
221         int             i, j;
222
223         tvbuff_t        *tvb_small[3];
224         tvbuff_t        *tvb_large[3];
225         tvbuff_t        *tvb_subset[6];
226         tvbuff_t        *tvb_comp[6];
227         guint8          *small[3];
228         guint8          *large[3];
229         guint8          *subset[6];
230         guint           subset_length[6];
231         guint8          *comp[6];
232         guint           comp_length[6];
233         guint8          temp;
234         int             len;
235
236         for (i = 0; i < 3; i++) {
237                 small[i] = g_new(guint8, 16);
238
239                 temp = 16 * i;
240                 for (j = 0; j < 16; j++) {
241                         small[i][j] = temp + j;
242                 }
243
244                 tvb_small[i] = tvb_new_real_data(small[i], 16);
245         }
246
247         for (i = 0; i < 3; i++) {
248                 large[i] = g_new(guint8, 19);
249
250                 temp = 19 * i;
251                 for (j = 0; j < 19; j++) {
252                         large[i][j] = temp + j;
253                 }
254
255                 tvb_large[i] = tvb_new_real_data(large[i], 19);
256         }
257
258         /* Test the TVBUFF_REAL_DATA objects. */
259         test(tvb_small[0], "Small 0", small[0], 16);
260         test(tvb_small[1], "Small 1", small[1], 16);
261         test(tvb_small[2], "Small 2", small[2], 16);
262
263         test(tvb_large[0], "Large 0", large[0], 19);
264         test(tvb_large[1], "Large 1", large[1], 19);
265         test(tvb_large[2], "Large 2", large[2], 19);
266
267         tvb_subset[0]           = tvb_new_subset(tvb_small[0], 0, 8);
268         subset[0]               = &small[0][0];
269         subset_length[0]        = 8;
270
271         tvb_subset[1]           = tvb_new_subset(tvb_large[0], -10, 10);
272         subset[1]               = &large[0][9];
273         subset_length[1]        = 10;
274
275         tvb_subset[2]           = tvb_new_subset(tvb_small[1], -16, -1);
276         subset[2]               = &small[1][0];
277         subset_length[2]        = 16;
278
279         tvb_subset[3]           = tvb_new_subset(tvb_subset[0], 0, 3);
280         subset[3]               = &small[0][0];
281         subset_length[3]        = 3;
282
283         tvb_subset[4]           = tvb_new_subset(tvb_subset[1], -5, 5);
284         subset[4]               = &large[0][14];
285         subset_length[4]        = 5;
286
287         tvb_subset[5]           = tvb_new_subset(tvb_subset[2], 4, 8);
288         subset[5]               = &small[1][4];
289         subset_length[5]        = 8;
290
291         /* Test the TVBUFF_SUBSET objects. */
292         test(tvb_subset[0], "Subset 0", subset[0], subset_length[0]);
293         test(tvb_subset[1], "Subset 1", subset[1], subset_length[1]);
294         test(tvb_subset[2], "Subset 2", subset[2], subset_length[2]);
295         test(tvb_subset[3], "Subset 3", subset[3], subset_length[3]);
296         test(tvb_subset[4], "Subset 4", subset[4], subset_length[4]);
297         test(tvb_subset[5], "Subset 5", subset[5], subset_length[5]);
298
299         /* One Real */
300         printf("Making Composite 0\n");
301         tvb_comp[0]             = tvb_new_composite();
302         comp[0]                 = small[0];
303         comp_length[0]          = 16;
304         tvb_composite_append(tvb_comp[0], tvb_small[0]);
305         tvb_composite_finalize(tvb_comp[0]);
306
307         /* Two Reals */
308         printf("Making Composite 1\n");
309         tvb_comp[1]             = tvb_new_composite();
310         comp[1]                 = g_malloc(32);
311         comp_length[1]          = 32;
312         memcpy(comp[1], small[0], 16);
313         memcpy(&comp[1][16], small[1], 16);
314         tvb_composite_append(tvb_comp[1], tvb_small[0]);
315         tvb_composite_append(tvb_comp[1], tvb_small[1]);
316         tvb_composite_finalize(tvb_comp[1]);
317
318         /* One subset */
319         printf("Making Composite 2\n");
320         tvb_comp[2]             = tvb_new_composite();
321         comp[2]                 = subset[1];
322         comp_length[2]          = subset_length[1];
323         tvb_composite_append(tvb_comp[2], tvb_subset[1]);
324         tvb_composite_finalize(tvb_comp[2]);
325
326         /* Two subsets */
327         printf("Making Composite 3\n");
328         tvb_comp[3]             = tvb_new_composite();
329         comp[3]                 = g_malloc(13);
330         comp_length[3]          = 13;
331         memcpy(comp[3], &large[0][14], 5);
332         memcpy(&comp[3][5], &small[1][4], 8);
333         tvb_composite_append(tvb_comp[3], tvb_subset[4]);
334         tvb_composite_append(tvb_comp[3], tvb_subset[5]);
335         tvb_composite_finalize(tvb_comp[3]);
336
337         /* One real, one subset */
338         printf("Making Composite 4\n");
339         tvb_comp[4]             = tvb_new_composite();
340         comp[4]                 = g_malloc(16 + subset_length[1]);
341         comp_length[4]          = 16 + subset_length[1];
342         memcpy(comp[4], small[0], 16);
343         memcpy(&comp[4][16], subset[1], subset_length[1]);
344         tvb_composite_append(tvb_comp[4], tvb_small[0]);
345         tvb_composite_append(tvb_comp[4], tvb_subset[1]);
346         tvb_composite_finalize(tvb_comp[4]);
347
348         /* 4 composites */
349         printf("Making Composite 5\n");
350         tvb_comp[5]             = tvb_new_composite();
351         comp_length[5]          = comp_length[0] + 
352                                         comp_length[1] +
353                                         comp_length[2] +
354                                         comp_length[3];
355         comp[5]                 = g_malloc(comp_length[5]);
356
357         len = 0;
358         memcpy(&comp[5][len], comp[0], comp_length[0]);
359         len += comp_length[0];
360         memcpy(&comp[5][len], comp[1], comp_length[1]);
361         len += comp_length[1];
362         memcpy(&comp[5][len], comp[2], comp_length[2]);
363         len += comp_length[2];
364         memcpy(&comp[5][len], comp[3], comp_length[3]);
365
366         tvb_composite_append(tvb_comp[5], tvb_comp[0]);
367         tvb_composite_append(tvb_comp[5], tvb_comp[1]);
368         tvb_composite_append(tvb_comp[5], tvb_comp[2]);
369         tvb_composite_append(tvb_comp[5], tvb_comp[3]);
370         tvb_composite_finalize(tvb_comp[5]);
371
372         /* Test the TVBUFF_COMPOSITE objects. */
373         test(tvb_comp[0], "Composite 0", comp[0], comp_length[0]);
374         test(tvb_comp[1], "Composite 1", comp[1], comp_length[1]);
375         test(tvb_comp[2], "Composite 2", comp[2], comp_length[2]);
376         test(tvb_comp[3], "Composite 3", comp[3], comp_length[3]);
377         test(tvb_comp[4], "Composite 4", comp[4], comp_length[4]);
378         test(tvb_comp[5], "Composite 5", comp[5], comp_length[5]);
379 }
380
381 int
382 main(void)
383 {
384         except_init();
385         tvbuff_init();
386         run_tests();
387         tvbuff_cleanup();
388         except_deinit();
389         exit(0);
390 }
391
392