diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2001-02-27 19:23:30 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2001-02-27 19:23:30 +0000 |
commit | 2a50f8af4f18dab44ee5414aa2c47fef3ab18e9d (patch) | |
tree | 9fba9ac63ac5a5f60b1519bb9bcf76112e1fbd78 /epan/ftypes/ftypes.c | |
parent | a954a9d276678fb6ff357ffa7be0a1609415fc0d (diff) |
Add Ed Warnicke's drange code to the new dfilter system.
Not supported yet: [i-j] (offset-offset)
Supported:
[i] index
[i:j] offset:length
[:j] 0:offset
[i:] offset:end
[x,y] concatenation of slices
svn path=/trunk/; revision=3080
Diffstat (limited to 'epan/ftypes/ftypes.c')
-rw-r--r-- | epan/ftypes/ftypes.c | 118 |
1 files changed, 72 insertions, 46 deletions
diff --git a/epan/ftypes/ftypes.c b/epan/ftypes/ftypes.c index 109104f249..3c1ea35b68 100644 --- a/epan/ftypes/ftypes.c +++ b/epan/ftypes/ftypes.c @@ -1,5 +1,5 @@ /* - * $Id: ftypes.c,v 1.2 2001/02/01 20:31:21 gram Exp $ + * $Id: ftypes.c,v 1.3 2001/02/27 19:23:30 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -274,68 +274,94 @@ fvalue_length(fvalue_t *fv) return fv->ftype->wire_size; } -/* Returns a new FT_BYTES fvalue_t* if possible, otherwise NULL */ -fvalue_t* -fvalue_slice(fvalue_t *fv, gint start, gint end) -{ +typedef struct { + fvalue_t *fv; GByteArray *bytes; - guint data_length, abs_end; - guint offset=0, length=0; - fvalue_t *new_fv; + gboolean slice_failure; +} slice_data_t; + +static void +slice_func(gpointer data, gpointer user_data) +{ + drange_node *drnode = data; + slice_data_t *slice_data = user_data; + gint offset; + gint length; + guint field_length; + guint end_offset; + gboolean to_end; + fvalue_t *fv; - if (!fv->ftype->slice) { - return NULL; + if (slice_data->slice_failure) { + return; } - data_length = fvalue_length(fv); - bytes = g_byte_array_new(); + offset = drange_node_get_offset(drnode); + length = drange_node_get_length(drnode); + to_end = drange_node_get_to_the_end(drnode); - /* Find absolute start position (offset) */ - if (start < 0) { - start = data_length + start; - if (start < 0) { - offset = 0; - } - else { - offset = start; - } - } - else { - offset = start; - } + fv = slice_data->fv; + field_length = fvalue_length(fv); - /* Limit the offset value */ - if (offset > data_length) { - offset = data_length; +/* g_debug("field_length=%u offset=%d length=%d", + field_length, offset, length);*/ + + if (offset < 0) { + offset = field_length + offset; } - /* Find absolute end position (abs_end) */ - if (end < 0) { - end = data_length + end; - if (end < 0) { - abs_end = 0; + if (to_end) { + end_offset = field_length; + length = end_offset - offset; + } + else { + if (length < 0) { + end_offset = field_length + length; + if (end_offset >= offset) { + length = end_offset - offset; + } + else { + length = 0; + } } else { - abs_end = end; + end_offset = offset + length; } } - else { - abs_end = end; - } - /* Limit the abs_end value */ - if (abs_end > data_length) { - abs_end = data_length; - } - /* Does end position occur *after* start position? */ - if (abs_end > offset) { - length = abs_end - offset; - fv->ftype->slice(fv, bytes, offset, length); +/* g_debug("\t\t(NEW) offset=%d length=%d", + offset, length);*/ + + if (offset > field_length || end_offset > field_length) { + slice_data->slice_failure = TRUE; + return; } + fv->ftype->slice(fv, slice_data->bytes, offset, length); +} + + +/* Returns a new FT_BYTES fvalue_t* if possible, otherwise NULL */ +fvalue_t* +fvalue_slice(fvalue_t *fv, drange *drange) +{ + slice_data_t slice_data; + fvalue_t *new_fv; + + slice_data.fv = fv; + slice_data.bytes = g_byte_array_new(); + slice_data.slice_failure = FALSE; + + /* XXX - We could make some optimizations here based on + * drange_has_total_length() and + * drange_get_max_offset(). + */ + + drange_foreach_drange_node(drange, slice_func, &slice_data); + new_fv = fvalue_new(FT_BYTES); - fvalue_set(new_fv, bytes, TRUE); + fvalue_set(new_fv, slice_data.bytes, TRUE); return new_fv; } |