aboutsummaryrefslogtreecommitdiffstats
path: root/epan/ftypes/ftypes.c
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2001-02-27 19:23:30 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2001-02-27 19:23:30 +0000
commit2a50f8af4f18dab44ee5414aa2c47fef3ab18e9d (patch)
tree9fba9ac63ac5a5f60b1519bb9bcf76112e1fbd78 /epan/ftypes/ftypes.c
parenta954a9d276678fb6ff357ffa7be0a1609415fc0d (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.c118
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;
}