Move tvb real and subset implementations to seperate files.

svn path=/trunk/; revision=50569
This commit is contained in:
Jakub Zawadzki 2013-07-14 07:42:19 +00:00
parent c089afca5c
commit 0d85b75305
6 changed files with 340 additions and 259 deletions

View File

@ -1498,6 +1498,8 @@ set(LIBWIRESHARK_FILES
to_str.c
tvbparse.c
tvbuff.c
tvbuff_real.c
tvbuff_subset.c
uat.c
value_string.c
xdlc.c

View File

@ -98,6 +98,8 @@ LIBWIRESHARK_SRC = \
tfs.c \
to_str.c \
tvbparse.c \
tvbuff_real.c \
tvbuff_subset.c \
tvbuff.c \
uat.c \
value_string.c \

View File

@ -97,13 +97,6 @@ struct tvbuff {
gint raw_offset;
};
struct tvb_real {
struct tvbuff tvb;
/** Func to call when actually freed */
tvbuff_free_cb_t free_cb;
};
struct tvb_subset {
struct tvbuff tvb;
@ -118,4 +111,9 @@ struct tvb_composite {
WS_DLL_PUBLIC tvbuff_t *tvb_new(const struct tvb_ops *ops);
void tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child);
guint tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter);
void tvb_check_offset_length(const tvbuff_t *tvb, const gint offset, gint const length_val, guint *offset_ptr, guint *length_ptr);
#endif

View File

@ -51,8 +51,6 @@
#include "charsets.h"
#include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
static inline const struct tvb_ops *get_tvb_real_ops(void);
static inline const struct tvb_ops *get_tvb_subset_ops(void);
static inline const struct tvb_ops *get_tvb_composite_ops(void);
static const guint8*
@ -86,19 +84,6 @@ tvb_new(const struct tvb_ops *ops)
return tvb;
}
static void
real_free(tvbuff_t *tvb)
{
struct tvb_real *real_tvb = (struct tvb_real *) tvb;
if (real_tvb->free_cb) {
/*
* XXX - do this with a union?
*/
real_tvb->free_cb((gpointer)tvb->real_data);
}
}
static void
composite_free(tvbuff_t *tvb)
{
@ -158,17 +143,7 @@ tvb_free_chain(tvbuff_t *tvb)
}
void
tvb_set_free_cb(tvbuff_t *tvb, const tvbuff_free_cb_t func)
{
struct tvb_real *real_tvb = (struct tvb_real *) tvb;
DISSECTOR_ASSERT(tvb);
DISSECTOR_ASSERT(tvb->ops == get_tvb_real_ops());
real_tvb->free_cb = func;
}
static void
add_to_chain(tvbuff_t *parent, tvbuff_t *child)
tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
{
DISSECTOR_ASSERT(parent && child);
DISSECTOR_ASSERT(!child->next && !child->previous);
@ -179,43 +154,6 @@ add_to_chain(tvbuff_t *parent, tvbuff_t *child)
parent->next = child;
}
void
tvb_set_child_real_data_tvbuff(tvbuff_t *parent, tvbuff_t *child)
{
DISSECTOR_ASSERT(parent && child);
DISSECTOR_ASSERT(parent->initialized);
DISSECTOR_ASSERT(child->initialized);
DISSECTOR_ASSERT(child->ops == get_tvb_real_ops());
add_to_chain(parent, child);
}
tvbuff_t *
tvb_new_real_data(const guint8* data, const guint length, const gint reported_length)
{
tvbuff_t *tvb;
struct tvb_real *real_tvb;
THROW_ON(reported_length < -1, ReportedBoundsError);
tvb = tvb_new(get_tvb_real_ops());
tvb->real_data = data;
tvb->length = length;
tvb->reported_length = reported_length;
tvb->initialized = TRUE;
/*
* This is the top-level real tvbuff for this data source,
* so its data source tvbuff is itself.
*/
tvb->ds_tvb = tvb;
real_tvb = (struct tvb_real *) tvb;
real_tvb->free_cb = NULL;
return tvb;
}
tvbuff_t *
tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, const guint length, const gint reported_length)
{
@ -349,110 +287,12 @@ check_offset_length(const tvbuff_t *tvb,
THROW(exception);
}
static tvbuff_t *
tvb_new_with_subset(tvbuff_t *backing, const gint reported_length,
const guint subset_tvb_offset, const guint subset_tvb_length)
void
tvb_check_offset_length(const tvbuff_t *tvb,
const gint offset, gint const length_val,
guint *offset_ptr, guint *length_ptr)
{
tvbuff_t *tvb = tvb_new(get_tvb_subset_ops());
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
subset_tvb->subset.offset = subset_tvb_offset;
subset_tvb->subset.length = subset_tvb_length;
subset_tvb->subset.tvb = backing;
tvb->length = subset_tvb_length;
tvb->flags = backing->flags;
if (reported_length == -1) {
tvb->reported_length = backing->reported_length - subset_tvb_offset;
}
else {
tvb->reported_length = reported_length;
}
tvb->initialized = TRUE;
add_to_chain(backing, tvb);
/* Optimization. If the backing buffer has a pointer to contiguous, real data,
* then we can point directly to our starting offset in that buffer */
if (backing->real_data != NULL) {
tvb->real_data = backing->real_data + subset_tvb_offset;
}
/*
* The top-level data source of this tvbuff is the top-level
* data source of its parent.
*/
tvb->ds_tvb = backing->ds_tvb;
return tvb;
}
tvbuff_t *
tvb_new_subset(tvbuff_t *backing, const gint backing_offset, const gint backing_length, const gint reported_length)
{
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
DISSECTOR_ASSERT(backing && backing->initialized);
THROW_ON(reported_length < -1, ReportedBoundsError);
check_offset_length(backing, backing_offset, backing_length,
&subset_tvb_offset,
&subset_tvb_length);
tvb = tvb_new_with_subset(backing, reported_length,
subset_tvb_offset, subset_tvb_length);
return tvb;
}
tvbuff_t *
tvb_new_subset_length(tvbuff_t *backing, const gint backing_offset, const gint backing_length)
{
gint captured_length;
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
DISSECTOR_ASSERT(backing && backing->initialized);
THROW_ON(backing_length < 0, ReportedBoundsError);
/*
* Give the next dissector only captured_length bytes.
*/
captured_length = tvb_length_remaining(backing, backing_offset);
THROW_ON(captured_length < 0, BoundsError);
if (captured_length > backing_length)
captured_length = backing_length;
check_offset_length(backing, backing_offset, captured_length,
&subset_tvb_offset,
&subset_tvb_length);
tvb = tvb_new_with_subset(backing, backing_length,
subset_tvb_offset, subset_tvb_length);
return tvb;
}
tvbuff_t *
tvb_new_subset_remaining(tvbuff_t *backing, const gint backing_offset)
{
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
check_offset_length(backing, backing_offset, -1 /* backing_length */,
&subset_tvb_offset,
&subset_tvb_length);
tvb = tvb_new_with_subset(backing, -1 /* reported_length */,
subset_tvb_offset, subset_tvb_length);
return tvb;
check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
}
static const unsigned char left_aligned_bitmask[] = {
@ -625,7 +465,7 @@ tvb_composite_finalize(tvbuff_t *tvb)
composite->end_offsets[i] = tvb->length - 1;
i++;
}
add_to_chain((tvbuff_t *)composite->tvbs->data, tvb); /* chain composite tvb to first member */
tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb); /* chain composite tvb to first member */
tvb->initialized = TRUE;
}
@ -849,8 +689,8 @@ first_real_data_ptr(tvbuff_t *tvb)
}
#endif
static guint
offset_from_real_beginning(const tvbuff_t *tvb, const guint counter)
guint
tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
{
if (tvb->ops->tvb_offset)
return tvb->ops->tvb_offset(tvb, counter);
@ -859,34 +699,19 @@ offset_from_real_beginning(const tvbuff_t *tvb, const guint counter)
return 0;
}
static guint
real_offset(const tvbuff_t *tvb _U_, const guint counter)
{
return counter;
}
static guint
subset_offset(const tvbuff_t *tvb, const guint counter)
{
const struct tvb_subset *subset_tvb = (const struct tvb_subset *) tvb;
const tvbuff_t *member = subset_tvb->subset.tvb;
return offset_from_real_beginning(member, counter + subset_tvb->subset.offset);
}
static guint
composite_offset(const tvbuff_t *tvb, const guint counter)
{
const struct tvb_composite *composite_tvb = (const struct tvb_composite *) tvb;
const tvbuff_t *member = (const tvbuff_t *)composite_tvb->composite.tvbs->data;
return offset_from_real_beginning(member, counter);
return tvb_offset_from_real_beginning_counter(member, counter);
}
guint
tvb_offset_from_real_beginning(const tvbuff_t *tvb)
{
return offset_from_real_beginning(tvb, 0);
return tvb_offset_from_real_beginning_counter(tvb, 0);
}
static const guint8*
@ -963,14 +788,6 @@ ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint leng
return NULL;
}
static const guint8 *
subset_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return ensure_contiguous_no_exception(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, abs_length, NULL);
}
static const guint8*
ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
{
@ -1109,14 +926,6 @@ composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, size_t abs_leng
DISSECTOR_ASSERT_NOT_REACHED();
}
static void *
subset_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_memcpy(subset_tvb->subset.tvb, target, subset_tvb->subset.offset + abs_offset, abs_length);
}
void *
tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
{
@ -1962,14 +1771,6 @@ tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const gu
return -1;
}
static gint
subset_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_find_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needle);
}
/* Find first occurrence of any of the needles in tvbuff, starting at offset.
* Searches at most maxlength number of bytes; if maxlength is -1, searches
* to end of tvbuff.
@ -2025,20 +1826,6 @@ tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const gu
return -1;
}
static gint
subset_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_pbrk_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needles, found_needle);
}
static tvbuff_t *
subset_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
{
return tvb_clone_offset_len(tvb, abs_offset, abs_length);
}
/* Find size of stringz (NUL-terminated string) by looking for terminating
* NUL. The size of the string includes the terminating NUL.
*
@ -3672,36 +3459,8 @@ tvb_get_ds_tvb(tvbuff_t *tvb)
return(tvb->ds_tvb);
}
static gsize real_sizeof(void) { return sizeof(struct tvb_real); }
static gsize subset_sizeof(void) { return sizeof(struct tvb_subset); }
static gsize composite_sizeof(void) { return sizeof(struct tvb_composite); }
static const struct tvb_ops tvb_real_ops = {
real_sizeof, /* size */
real_free, /* free */
real_offset, /* offset */
NULL, /* get_ptr */
NULL, /* memcpy */
NULL, /* find_guint8 */
NULL, /* pbrk_guint8 */
NULL, /* clone */
};
static inline const struct tvb_ops *get_tvb_real_ops(void) { return &tvb_real_ops; }
static const struct tvb_ops tvb_subset_ops = {
subset_sizeof, /* size */
NULL, /* free */
subset_offset, /* offset */
subset_get_ptr, /* get_ptr */
subset_memcpy, /* memcpy */
subset_find_guint8, /* find_guint8 */
subset_pbrk_guint8, /* pbrk_guint8 */
subset_clone, /* clone */
};
static inline const struct tvb_ops *get_tvb_subset_ops(void) { return &tvb_subset_ops; }
static const struct tvb_ops tvb_composite_ops = {
composite_sizeof, /* size */
composite_free, /* free */

120
epan/tvbuff_real.c Normal file
View File

@ -0,0 +1,120 @@
/* tvbuff_real.c
*
* $Id$
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "tvbuff.h"
#include "tvbuff-int.h"
#include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
struct tvb_real {
struct tvbuff tvb;
/** Func to call when actually freed */
tvbuff_free_cb_t free_cb;
};
static gsize
real_sizeof(void)
{
return sizeof(struct tvb_real);
}
static void
real_free(tvbuff_t *tvb)
{
struct tvb_real *real_tvb = (struct tvb_real *) tvb;
if (real_tvb->free_cb) {
/*
* XXX - do this with a union?
*/
real_tvb->free_cb((gpointer)tvb->real_data);
}
}
static guint
real_offset(const tvbuff_t *tvb _U_, const guint counter)
{
return counter;
}
static const struct tvb_ops tvb_real_ops = {
real_sizeof, /* size */
real_free, /* free */
real_offset, /* offset */
NULL, /* get_ptr */
NULL, /* memcpy */
NULL, /* find_guint8 */
NULL, /* pbrk_guint8 */
NULL, /* clone */
};
tvbuff_t *
tvb_new_real_data(const guint8* data, const guint length, const gint reported_length)
{
tvbuff_t *tvb;
struct tvb_real *real_tvb;
THROW_ON(reported_length < -1, ReportedBoundsError);
tvb = tvb_new(&tvb_real_ops);
tvb->real_data = data;
tvb->length = length;
tvb->reported_length = reported_length;
tvb->initialized = TRUE;
/*
* This is the top-level real tvbuff for this data source,
* so its data source tvbuff is itself.
*/
tvb->ds_tvb = tvb;
real_tvb = (struct tvb_real *) tvb;
real_tvb->free_cb = NULL;
return tvb;
}
void
tvb_set_free_cb(tvbuff_t *tvb, const tvbuff_free_cb_t func)
{
struct tvb_real *real_tvb = (struct tvb_real *) tvb;
DISSECTOR_ASSERT(tvb);
DISSECTOR_ASSERT(tvb->ops == &tvb_real_ops);
real_tvb->free_cb = func;
}
void
tvb_set_child_real_data_tvbuff(tvbuff_t *parent, tvbuff_t *child)
{
DISSECTOR_ASSERT(parent && child);
DISSECTOR_ASSERT(parent->initialized);
DISSECTOR_ASSERT(child->initialized);
DISSECTOR_ASSERT(child->ops == &tvb_real_ops);
tvb_add_to_chain(parent, child);
}

200
epan/tvbuff_subset.c Normal file
View File

@ -0,0 +1,200 @@
/* tvbuff_real.c
*
* $Id$
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "tvbuff.h"
#include "tvbuff-int.h"
#include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
static gsize
subset_sizeof(void)
{
return sizeof(struct tvb_subset);
}
static guint
subset_offset(const tvbuff_t *tvb, const guint counter)
{
const struct tvb_subset *subset_tvb = (const struct tvb_subset *) tvb;
const tvbuff_t *member = subset_tvb->subset.tvb;
return tvb_offset_from_real_beginning_counter(member, counter + subset_tvb->subset.offset);
}
static void *
subset_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_memcpy(subset_tvb->subset.tvb, target, subset_tvb->subset.offset + abs_offset, abs_length);
}
static const guint8 *
subset_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_get_ptr(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, abs_length);
}
static gint
subset_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_find_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needle);
}
static gint
subset_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle)
{
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
return tvb_pbrk_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needles, found_needle);
}
static tvbuff_t *
subset_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
{
return tvb_clone_offset_len(tvb, abs_offset, abs_length);
}
static const struct tvb_ops tvb_subset_ops = {
subset_sizeof, /* size */
NULL, /* free */
subset_offset, /* offset */
subset_get_ptr, /* get_ptr */
subset_memcpy, /* memcpy */
subset_find_guint8, /* find_guint8 */
subset_pbrk_guint8, /* pbrk_guint8 */
subset_clone, /* clone */
};
static tvbuff_t *
tvb_new_with_subset(tvbuff_t *backing, const gint reported_length,
const guint subset_tvb_offset, const guint subset_tvb_length)
{
tvbuff_t *tvb = tvb_new(&tvb_subset_ops);
struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
subset_tvb->subset.offset = subset_tvb_offset;
subset_tvb->subset.length = subset_tvb_length;
subset_tvb->subset.tvb = backing;
tvb->length = subset_tvb_length;
tvb->flags = backing->flags;
if (reported_length == -1) {
tvb->reported_length = backing->reported_length - subset_tvb_offset;
}
else {
tvb->reported_length = reported_length;
}
tvb->initialized = TRUE;
tvb_add_to_chain(backing, tvb);
/* Optimization. If the backing buffer has a pointer to contiguous, real data,
* then we can point directly to our starting offset in that buffer */
if (backing->real_data != NULL) {
tvb->real_data = backing->real_data + subset_tvb_offset;
}
/*
* The top-level data source of this tvbuff is the top-level
* data source of its parent.
*/
tvb->ds_tvb = backing->ds_tvb;
return tvb;
}
tvbuff_t *
tvb_new_subset(tvbuff_t *backing, const gint backing_offset, const gint backing_length, const gint reported_length)
{
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
DISSECTOR_ASSERT(backing && backing->initialized);
THROW_ON(reported_length < -1, ReportedBoundsError);
tvb_check_offset_length(backing, backing_offset, backing_length,
&subset_tvb_offset,
&subset_tvb_length);
tvb = tvb_new_with_subset(backing, reported_length,
subset_tvb_offset, subset_tvb_length);
return tvb;
}
tvbuff_t *
tvb_new_subset_length(tvbuff_t *backing, const gint backing_offset, const gint backing_length)
{
gint captured_length;
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
DISSECTOR_ASSERT(backing && backing->initialized);
THROW_ON(backing_length < 0, ReportedBoundsError);
/*
* Give the next dissector only captured_length bytes.
*/
captured_length = tvb_length_remaining(backing, backing_offset);
THROW_ON(captured_length < 0, BoundsError);
if (captured_length > backing_length)
captured_length = backing_length;
tvb_check_offset_length(backing, backing_offset, captured_length,
&subset_tvb_offset,
&subset_tvb_length);
tvb = tvb_new_with_subset(backing, backing_length,
subset_tvb_offset, subset_tvb_length);
return tvb;
}
tvbuff_t *
tvb_new_subset_remaining(tvbuff_t *backing, const gint backing_offset)
{
tvbuff_t *tvb;
guint subset_tvb_offset;
guint subset_tvb_length;
tvb_check_offset_length(backing, backing_offset, -1 /* backing_length */,
&subset_tvb_offset,
&subset_tvb_length);
tvb = tvb_new_with_subset(backing, -1 /* reported_length */,
subset_tvb_offset, subset_tvb_length);
return tvb;
}