MSWSP: parse_CColumnGroupArray() etc.
[wireshark-wip.git] / epan / ftypes / ftype-tvbuff.c
blobe7bacae0628c4e42cc639823cbd185f540a48a3b
1 /*
2 * $Id$
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 2001 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "config.h"
25 #include <stdio.h>
26 #include <ftypes-int.h>
27 #include <string.h>
29 #include <epan/exceptions.h>
31 #define CMP_MATCHES cmp_matches
33 #define tvb_is_private fvalue_gboolean1
35 static void
36 value_new(fvalue_t *fv)
38 fv->value.tvb = NULL;
39 fv->tvb_is_private = FALSE;
42 static void
43 value_free(fvalue_t *fv)
45 if (fv->value.tvb && fv->tvb_is_private) {
46 tvb_free_chain(fv->value.tvb);
50 static void
51 value_set(fvalue_t *fv, gpointer value, gboolean already_copied)
53 g_assert(already_copied);
55 /* Free up the old value, if we have one */
56 value_free(fv);
58 fv->value.tvb = (tvbuff_t *)value;
61 static void
62 free_tvb_data(void *data)
64 g_free(data);
67 static gboolean
68 val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
70 tvbuff_t *new_tvb;
71 guint8 *private_data;
73 /* Free up the old value, if we have one */
74 value_free(fv);
76 /* Make a tvbuff from the string. We can drop the
77 * terminating NUL. */
78 private_data = (guint8 *)g_memdup(s, (guint)strlen(s));
79 new_tvb = tvb_new_real_data(private_data,
80 (guint)strlen(s), (gint)strlen(s));
82 /* Let the tvbuff know how to delete the data. */
83 tvb_set_free_cb(new_tvb, free_tvb_data);
85 /* And let us know that we need to free the tvbuff */
86 fv->tvb_is_private = TRUE;
87 fv->value.tvb = new_tvb;
88 return TRUE;
91 static gboolean
92 val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
94 fvalue_t *fv_bytes;
95 tvbuff_t *new_tvb;
96 guint8 *private_data;
98 /* Free up the old value, if we have one */
99 value_free(fv);
101 /* Does this look like a byte string? */
102 fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
103 if (fv_bytes) {
104 /* Make a tvbuff from the bytes */
105 private_data = (guint8 *)g_memdup(fv_bytes->value.bytes->data,
106 fv_bytes->value.bytes->len);
107 new_tvb = tvb_new_real_data(private_data,
108 fv_bytes->value.bytes->len,
109 fv_bytes->value.bytes->len);
111 /* Let the tvbuff know how to delete the data. */
112 tvb_set_free_cb(new_tvb, free_tvb_data);
114 /* And let us know that we need to free the tvbuff */
115 fv->tvb_is_private = TRUE;
116 fv->value.tvb = new_tvb;
117 return TRUE;
120 /* Treat it as a string. */
121 return val_from_string(fv, s, logfunc);
124 static int
125 val_repr_len(fvalue_t *fv, ftrepr_t rtype)
127 volatile guint length = 0;
129 if (rtype != FTREPR_DFILTER) return -1;
131 TRY {
132 /* 3 bytes for each byte of the byte "NN:" minus 1 byte
133 * as there's no trailing ":". */
134 length = tvb_length(fv->value.tvb) * 3 - 1;
136 CATCH_ALL {
137 /* nothing */
139 ENDTRY;
141 return (int) length;
144 static void
145 val_to_repr(fvalue_t *fv, ftrepr_t rtype, char * volatile buf)
147 guint length;
148 const guint8 *c;
149 unsigned int i;
151 g_assert(rtype == FTREPR_DFILTER);
153 TRY {
154 length = tvb_length(fv->value.tvb);
155 c = tvb_get_ptr(fv->value.tvb, 0, length);
157 for (i = 0; i < length; i++) {
158 if (i == 0) {
159 sprintf((char *)buf, "%02x", *c++);
160 buf += 2;
162 else {
163 sprintf((char *)buf, ":%02x", *c++);
164 buf += 3;
168 CATCH_ALL {
169 /* nothing */
171 ENDTRY;
174 static gpointer
175 value_get(fvalue_t *fv)
177 return fv->value.tvb;
180 static guint
181 len(fvalue_t *fv)
183 volatile guint length = 0;
185 TRY {
186 if (fv->value.tvb)
187 length = tvb_length(fv->value.tvb);
189 CATCH_ALL {
190 /* nothing */
192 ENDTRY;
194 return length;
197 static void
198 slice(fvalue_t *fv, GByteArray *bytes, guint offset, guint length)
200 const guint8* data;
202 if (fv->value.tvb) {
203 TRY {
204 data = tvb_get_ptr(fv->value.tvb, offset, length);
205 g_byte_array_append(bytes, data, length);
207 CATCH_ALL {
208 /* nothing */
210 ENDTRY;
215 static gboolean
216 cmp_eq(const fvalue_t *fv_a, const fvalue_t *fv_b)
218 tvbuff_t *a = fv_a->value.tvb;
219 tvbuff_t *b = fv_b->value.tvb;
220 volatile gboolean eq = FALSE;
222 TRY {
223 guint a_len = tvb_length(a);
225 if (a_len == tvb_length(b))
226 eq = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) == 0);
228 CATCH_ALL {
229 /* nothing */
231 ENDTRY;
233 return eq;
236 static gboolean
237 cmp_ne(const fvalue_t *fv_a, const fvalue_t *fv_b)
239 tvbuff_t *a = fv_a->value.tvb;
240 tvbuff_t *b = fv_b->value.tvb;
241 volatile gboolean ne = TRUE;
243 TRY {
244 guint a_len = tvb_length(a);
246 if (a_len == tvb_length(b)) {
247 ne = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) != 0);
250 CATCH_ALL {
251 /* nothing */
253 ENDTRY;
255 return ne;
258 static gboolean
259 cmp_gt(const fvalue_t *fv_a, const fvalue_t *fv_b)
261 tvbuff_t *a = fv_a->value.tvb;
262 tvbuff_t *b = fv_b->value.tvb;
263 volatile gboolean gt = FALSE;
265 TRY {
266 guint a_len = tvb_length(a);
267 guint b_len = tvb_length(b);
269 if (a_len > b_len) {
270 gt = TRUE;
271 } else if (a_len == b_len) {
272 gt = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) > 0);
275 CATCH_ALL {
276 /* nothing */
278 ENDTRY;
280 return gt;
283 static gboolean
284 cmp_ge(const fvalue_t *fv_a, const fvalue_t *fv_b)
286 tvbuff_t *a = fv_a->value.tvb;
287 tvbuff_t *b = fv_b->value.tvb;
288 volatile gboolean ge = FALSE;
290 TRY {
291 guint a_len = tvb_length(a);
292 guint b_len = tvb_length(b);
294 if (a_len > b_len) {
295 ge = TRUE;
296 } else if (a_len == b_len) {
297 ge = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) >= 0);
300 CATCH_ALL {
301 /* nothing */
303 ENDTRY;
305 return ge;
308 static gboolean
309 cmp_lt(const fvalue_t *fv_a, const fvalue_t *fv_b)
311 tvbuff_t *a = fv_a->value.tvb;
312 tvbuff_t *b = fv_b->value.tvb;
313 volatile gboolean lt = FALSE;
315 TRY {
316 guint a_len = tvb_length(a);
317 guint b_len = tvb_length(b);
319 if (a_len < b_len) {
320 lt = TRUE;
321 } else if (a_len == b_len) {
322 lt = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) < 0);
325 CATCH_ALL {
326 /* nothing */
328 ENDTRY;
330 return lt;
333 static gboolean
334 cmp_le(const fvalue_t *fv_a, const fvalue_t *fv_b)
336 tvbuff_t *a = fv_a->value.tvb;
337 tvbuff_t *b = fv_b->value.tvb;
338 volatile gboolean le = FALSE;
340 TRY {
341 guint a_len = tvb_length(a);
342 guint b_len = tvb_length(b);
344 if (a_len < b_len) {
345 le = TRUE;
346 } else if (a_len == b_len) {
347 le = (memcmp(tvb_get_ptr(a, 0, a_len), tvb_get_ptr(b, 0, a_len), a_len) <= 0);
350 CATCH_ALL {
351 /* nothing */
353 ENDTRY;
355 return le;
358 static gboolean
359 cmp_contains(const fvalue_t *fv_a, const fvalue_t *fv_b)
361 volatile gboolean contains = FALSE;
363 TRY {
364 if (tvb_find_tvb(fv_a->value.tvb, fv_b->value.tvb, 0) > -1) {
365 contains = TRUE;
368 CATCH_ALL {
369 /* nothing */
371 ENDTRY;
373 return contains;
376 static gboolean
377 cmp_matches(const fvalue_t *fv_a, const fvalue_t *fv_b)
379 tvbuff_t *tvb = fv_a->value.tvb;
380 GRegex *regex = fv_b->value.re;
381 volatile gboolean rc = FALSE;
382 const char *data = NULL; /* tvb data */
383 guint32 tvb_len; /* tvb length */
385 /* fv_b is always a FT_PCRE, otherwise the dfilter semcheck() would have
386 * warned us. For the same reason (and because we're using g_malloc()),
387 * fv_b->value.re is not NULL.
389 if (strcmp(fv_b->ftype->name, "FT_PCRE") != 0) {
390 return FALSE;
392 if (! regex) {
393 return FALSE;
395 TRY {
396 tvb_len = tvb_length(tvb);
397 data = (const char *)tvb_get_ptr(tvb, 0, tvb_len);
398 rc = g_regex_match_full(
399 regex, /* Compiled PCRE */
400 data, /* The data to check for the pattern... */
401 tvb_len, /* ... and its length */
402 0, /* Start offset within data */
403 (GRegexMatchFlags)0, /* GRegexMatchFlags */
404 NULL, /* We are not interested in the match information */
405 NULL /* We don't want error information */
407 /* NOTE - DO NOT g_free(data) */
409 CATCH_ALL {
410 return FALSE;
412 ENDTRY;
413 return rc;
416 void
417 ftype_register_tvbuff(void)
420 static ftype_t protocol_type = {
421 FT_PROTOCOL, /* ftype */
422 "FT_PROTOCOL", /* name */
423 "Protocol", /* pretty_name */
424 0, /* wire_size */
425 value_new, /* new_value */
426 value_free, /* free_value */
427 val_from_unparsed, /* val_from_unparsed */
428 val_from_string, /* val_from_string */
429 val_to_repr, /* val_to_string_repr */
430 val_repr_len, /* len_string_repr */
432 value_set, /* set_value */
433 NULL, /* set_value_uinteger */
434 NULL, /* set_value_sinteger */
435 NULL, /* set_value_integer64 */
436 NULL, /* set_value_floating */
438 value_get, /* get_value */
439 NULL, /* get_value_uinteger */
440 NULL, /* get_value_sinteger */
441 NULL, /* get_value_integer64 */
442 NULL, /* get_value_floating */
444 cmp_eq,
445 cmp_ne,
446 cmp_gt,
447 cmp_ge,
448 cmp_lt,
449 cmp_le,
450 NULL, /* cmp_bitwise_and */
451 cmp_contains,
452 CMP_MATCHES,
454 len,
455 slice,
460 ftype_register(FT_PROTOCOL, &protocol_type);