Move composite tvbuff to seperate file (with some subtle changes).
svn path=/trunk/; revision=51071
This commit is contained in:
parent
a9b8779fb9
commit
9d519b5659
|
@ -1499,6 +1499,7 @@ set(LIBWIRESHARK_FILES
|
|||
to_str.c
|
||||
tvbparse.c
|
||||
tvbuff.c
|
||||
tvbuff_composite.c
|
||||
tvbuff_real.c
|
||||
tvbuff_subset.c
|
||||
uat.c
|
||||
|
|
|
@ -97,6 +97,7 @@ LIBWIRESHARK_SRC = \
|
|||
tfs.c \
|
||||
to_str.c \
|
||||
tvbparse.c \
|
||||
tvbuff_composite.c \
|
||||
tvbuff_real.c \
|
||||
tvbuff_subset.c \
|
||||
tvbuff.c \
|
||||
|
|
257
epan/tvbuff.c
257
epan/tvbuff.c
|
@ -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_composite_ops(void);
|
||||
|
||||
static const guint8*
|
||||
ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length,
|
||||
int *pexception);
|
||||
|
@ -84,24 +82,6 @@ tvb_new(const struct tvb_ops *ops)
|
|||
return tvb;
|
||||
}
|
||||
|
||||
static void
|
||||
composite_free(tvbuff_t *tvb)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite = &composite_tvb->composite;
|
||||
|
||||
g_slist_free(composite->tvbs);
|
||||
|
||||
g_free(composite->start_offsets);
|
||||
g_free(composite->end_offsets);
|
||||
if (tvb->real_data) {
|
||||
/*
|
||||
* XXX - do this with a union?
|
||||
*/
|
||||
g_free((gpointer)tvb->real_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tvb_free_internal(tvbuff_t *tvb)
|
||||
{
|
||||
|
@ -397,105 +377,6 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
|
|||
return sub_tvb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Composite tvb
|
||||
*
|
||||
* 1. A composite tvb is automatically chained to its first member when the
|
||||
* tvb is finalized.
|
||||
* This means that composite tvb members must all be in the same chain.
|
||||
* ToDo: enforce this: By searching the chain?
|
||||
*/
|
||||
tvbuff_t *
|
||||
tvb_new_composite(void)
|
||||
{
|
||||
tvbuff_t *tvb = tvb_new(get_tvb_composite_ops());
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite = &composite_tvb->composite;
|
||||
|
||||
composite->tvbs = NULL;
|
||||
composite->start_offsets = NULL;
|
||||
composite->end_offsets = NULL;
|
||||
|
||||
return tvb;
|
||||
}
|
||||
|
||||
void
|
||||
tvb_composite_append(tvbuff_t *tvb, tvbuff_t *member)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite;
|
||||
|
||||
DISSECTOR_ASSERT(tvb && !tvb->initialized);
|
||||
DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops());
|
||||
|
||||
/* Don't allow zero-length TVBs: composite_memcpy() can't handle them
|
||||
* and anyway it makes no sense.
|
||||
*/
|
||||
DISSECTOR_ASSERT(member->length);
|
||||
|
||||
composite = &composite_tvb->composite;
|
||||
composite->tvbs = g_slist_append(composite->tvbs, member);
|
||||
}
|
||||
|
||||
void
|
||||
tvb_composite_prepend(tvbuff_t *tvb, tvbuff_t *member)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite;
|
||||
|
||||
DISSECTOR_ASSERT(tvb && !tvb->initialized);
|
||||
DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops());
|
||||
|
||||
/* Don't allow zero-length TVBs: composite_memcpy() can't handle them
|
||||
* and anyway it makes no sense.
|
||||
*/
|
||||
DISSECTOR_ASSERT(member->length);
|
||||
|
||||
composite = &composite_tvb->composite;
|
||||
composite->tvbs = g_slist_prepend(composite->tvbs, member);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tvb_composite_finalize(tvbuff_t *tvb)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
GSList *slist;
|
||||
guint num_members;
|
||||
tvbuff_t *member_tvb;
|
||||
tvb_comp_t *composite;
|
||||
int i = 0;
|
||||
|
||||
DISSECTOR_ASSERT(tvb && !tvb->initialized);
|
||||
DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops());
|
||||
DISSECTOR_ASSERT(tvb->length == 0);
|
||||
DISSECTOR_ASSERT(tvb->reported_length == 0);
|
||||
|
||||
composite = &composite_tvb->composite;
|
||||
num_members = g_slist_length(composite->tvbs);
|
||||
|
||||
/* Dissectors should not create composite TVBs if they're not going to
|
||||
* put at least one TVB in them.
|
||||
* (Without this check--or something similar--we'll seg-fault below.)
|
||||
*/
|
||||
DISSECTOR_ASSERT(num_members);
|
||||
|
||||
composite->start_offsets = g_new(guint, num_members);
|
||||
composite->end_offsets = g_new(guint, num_members);
|
||||
|
||||
for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
|
||||
DISSECTOR_ASSERT((guint) i < num_members);
|
||||
member_tvb = (tvbuff_t *)slist->data;
|
||||
composite->start_offsets[i] = tvb->length;
|
||||
tvb->length += member_tvb->length;
|
||||
tvb->reported_length += member_tvb->reported_length;
|
||||
composite->end_offsets[i] = tvb->length - 1;
|
||||
i++;
|
||||
}
|
||||
tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb); /* chain composite tvb to first member */
|
||||
tvb->initialized = TRUE;
|
||||
}
|
||||
|
||||
static tvbuff_t *
|
||||
tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
|
||||
{
|
||||
|
@ -726,67 +607,12 @@ tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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 tvb_offset_from_real_beginning_counter(member, counter);
|
||||
}
|
||||
|
||||
guint
|
||||
tvb_offset_from_real_beginning(const tvbuff_t *tvb)
|
||||
{
|
||||
return tvb_offset_from_real_beginning_counter(tvb, 0);
|
||||
}
|
||||
|
||||
static const guint8*
|
||||
composite_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
guint i, num_members;
|
||||
tvb_comp_t *composite;
|
||||
tvbuff_t *member_tvb = NULL;
|
||||
guint member_offset, member_length;
|
||||
GSList *slist;
|
||||
int exception;
|
||||
|
||||
DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops());
|
||||
|
||||
/* Maybe the range specified by offset/length
|
||||
* is contiguous inside one of the member tvbuffs */
|
||||
composite = &composite_tvb->composite;
|
||||
num_members = g_slist_length(composite->tvbs);
|
||||
|
||||
for (i = 0; i < num_members; i++) {
|
||||
if (abs_offset <= composite->end_offsets[i]) {
|
||||
slist = g_slist_nth(composite->tvbs, i);
|
||||
member_tvb = (tvbuff_t *)slist->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DISSECTOR_ASSERT(member_tvb);
|
||||
|
||||
exception = check_offset_length_no_exception(member_tvb,
|
||||
abs_offset - composite->start_offsets[i],
|
||||
abs_length, &member_offset, &member_length);
|
||||
|
||||
if (!exception) {
|
||||
/*
|
||||
* The range is, in fact, contiguous within member_tvb.
|
||||
*/
|
||||
DISSECTOR_ASSERT(!tvb->real_data);
|
||||
return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
|
||||
}
|
||||
else {
|
||||
tvb->real_data = (guint8 *)tvb_memdup(tvb, 0, -1);
|
||||
return tvb->real_data + abs_offset;
|
||||
}
|
||||
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
static const guint8*
|
||||
ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
|
||||
{
|
||||
|
@ -889,70 +715,6 @@ guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles, g
|
|||
|
||||
/************** ACCESSORS **************/
|
||||
|
||||
static void *
|
||||
composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, size_t abs_length)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
guint8 *target = (guint8 *) _target;
|
||||
|
||||
guint i, num_members;
|
||||
tvb_comp_t *composite;
|
||||
tvbuff_t *member_tvb = NULL;
|
||||
guint member_offset, member_length;
|
||||
int exception;
|
||||
GSList *slist;
|
||||
|
||||
DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops());
|
||||
|
||||
/* Maybe the range specified by offset/length
|
||||
* is contiguous inside one of the member tvbuffs */
|
||||
composite = &composite_tvb->composite;
|
||||
num_members = g_slist_length(composite->tvbs);
|
||||
|
||||
for (i = 0; i < num_members; i++) {
|
||||
if (abs_offset <= composite->end_offsets[i]) {
|
||||
slist = g_slist_nth(composite->tvbs, i);
|
||||
member_tvb = (tvbuff_t *)slist->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DISSECTOR_ASSERT(member_tvb);
|
||||
|
||||
exception = check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
|
||||
(gint) abs_length, &member_offset, &member_length);
|
||||
|
||||
if (!exception) {
|
||||
DISSECTOR_ASSERT(!tvb->real_data);
|
||||
return tvb_memcpy(member_tvb, target, member_offset, member_length);
|
||||
}
|
||||
else {
|
||||
/* The requested data is non-contiguous inside
|
||||
* the member tvb. We have to memcpy() the part that's in the member tvb,
|
||||
* then iterate across the other member tvb's, copying their portions
|
||||
* until we have copied all data.
|
||||
*/
|
||||
exception = compute_offset_and_remaining(member_tvb, abs_offset - composite->start_offsets[i],
|
||||
&member_offset, &member_length);
|
||||
DISSECTOR_ASSERT(!exception);
|
||||
|
||||
/* composite_memcpy() can't handle a member_length of zero. */
|
||||
DISSECTOR_ASSERT(member_length);
|
||||
|
||||
tvb_memcpy(member_tvb, target, member_offset, member_length);
|
||||
abs_offset += member_length;
|
||||
abs_length -= member_length;
|
||||
|
||||
/* Recurse */
|
||||
if (abs_length > 0) {
|
||||
composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
void *
|
||||
tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
|
||||
{
|
||||
|
@ -978,11 +740,6 @@ tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
|
|||
return memcpy(target, tvb->real_data + abs_offset, abs_length);
|
||||
}
|
||||
|
||||
if (tvb->ops == get_tvb_composite_ops()) {
|
||||
/* special case for composite, bug?! */
|
||||
return composite_memcpy(tvb, target, offset, length);
|
||||
}
|
||||
|
||||
if (tvb->ops->tvb_memcpy)
|
||||
return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
|
||||
|
||||
|
@ -3486,17 +3243,3 @@ tvb_get_ds_tvb(tvbuff_t *tvb)
|
|||
return(tvb->ds_tvb);
|
||||
}
|
||||
|
||||
static gsize composite_sizeof(void) { return sizeof(struct tvb_composite); }
|
||||
|
||||
static const struct tvb_ops tvb_composite_ops = {
|
||||
composite_sizeof, /* size */
|
||||
composite_free, /* free */
|
||||
composite_offset, /* offset */
|
||||
composite_get_ptr, /* get_ptr */
|
||||
NULL, /* composite_memcpy */ /* memcpy */
|
||||
NULL, /* find_guint8 XXX */
|
||||
NULL, /* pbrk_guint8 XXX */
|
||||
NULL, /* clone */
|
||||
};
|
||||
|
||||
static inline const struct tvb_ops *get_tvb_composite_ops(void) { return &tvb_composite_ops; }
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
/* tvbuff_composite.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
|
||||
composite_sizeof(void)
|
||||
{
|
||||
return sizeof(struct tvb_composite);
|
||||
}
|
||||
|
||||
static void
|
||||
composite_free(tvbuff_t *tvb)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite = &composite_tvb->composite;
|
||||
|
||||
g_slist_free(composite->tvbs);
|
||||
|
||||
g_free(composite->start_offsets);
|
||||
g_free(composite->end_offsets);
|
||||
if (tvb->real_data) {
|
||||
/*
|
||||
* XXX - do this with a union?
|
||||
*/
|
||||
g_free((gpointer)tvb->real_data);
|
||||
}
|
||||
}
|
||||
|
||||
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 tvb_offset_from_real_beginning_counter(member, counter);
|
||||
}
|
||||
|
||||
static const guint8*
|
||||
composite_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
guint i, num_members;
|
||||
tvb_comp_t *composite;
|
||||
tvbuff_t *member_tvb = NULL;
|
||||
guint member_offset;
|
||||
GSList *slist;
|
||||
|
||||
/* DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); */
|
||||
|
||||
/* Maybe the range specified by offset/length
|
||||
* is contiguous inside one of the member tvbuffs */
|
||||
composite = &composite_tvb->composite;
|
||||
num_members = g_slist_length(composite->tvbs);
|
||||
|
||||
for (i = 0; i < num_members; i++) {
|
||||
if (abs_offset <= composite->end_offsets[i]) {
|
||||
slist = g_slist_nth(composite->tvbs, i);
|
||||
member_tvb = (tvbuff_t *)slist->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DISSECTOR_ASSERT(member_tvb);
|
||||
|
||||
member_offset = abs_offset - composite->start_offsets[i];
|
||||
|
||||
if (tvb_bytes_exist(member_tvb, member_offset, abs_length)) {
|
||||
/*
|
||||
* The range is, in fact, contiguous within member_tvb.
|
||||
*/
|
||||
DISSECTOR_ASSERT(!tvb->real_data);
|
||||
return tvb_get_ptr(member_tvb, member_offset, abs_length);
|
||||
}
|
||||
else {
|
||||
tvb->real_data = (guint8 *)tvb_memdup(tvb, 0, -1);
|
||||
return tvb->real_data + abs_offset;
|
||||
}
|
||||
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
static void *
|
||||
composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, guint abs_length)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
guint8 *target = (guint8 *) _target;
|
||||
|
||||
guint i, num_members;
|
||||
tvb_comp_t *composite;
|
||||
tvbuff_t *member_tvb = NULL;
|
||||
guint member_offset, member_length;
|
||||
GSList *slist;
|
||||
|
||||
/* DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); */
|
||||
|
||||
/* Maybe the range specified by offset/length
|
||||
* is contiguous inside one of the member tvbuffs */
|
||||
composite = &composite_tvb->composite;
|
||||
num_members = g_slist_length(composite->tvbs);
|
||||
|
||||
for (i = 0; i < num_members; i++) {
|
||||
if (abs_offset <= composite->end_offsets[i]) {
|
||||
slist = g_slist_nth(composite->tvbs, i);
|
||||
member_tvb = (tvbuff_t *)slist->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DISSECTOR_ASSERT(member_tvb);
|
||||
|
||||
member_offset = abs_offset - composite->start_offsets[i];
|
||||
|
||||
if (tvb_bytes_exist(member_tvb, member_offset, abs_length)) {
|
||||
DISSECTOR_ASSERT(!tvb->real_data);
|
||||
return tvb_memcpy(member_tvb, target, member_offset, abs_length);
|
||||
}
|
||||
else {
|
||||
/* The requested data is non-contiguous inside
|
||||
* the member tvb. We have to memcpy() the part that's in the member tvb,
|
||||
* then iterate across the other member tvb's, copying their portions
|
||||
* until we have copied all data.
|
||||
*/
|
||||
member_length = tvb_length_remaining(member_tvb, member_offset);
|
||||
|
||||
/* composite_memcpy() can't handle a member_length of zero. */
|
||||
DISSECTOR_ASSERT(member_length > 0);
|
||||
|
||||
tvb_memcpy(member_tvb, target, member_offset, member_length);
|
||||
abs_offset += member_length;
|
||||
abs_length -= member_length;
|
||||
|
||||
/* Recurse */
|
||||
if (abs_length > 0) {
|
||||
composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
static const struct tvb_ops tvb_composite_ops = {
|
||||
composite_sizeof, /* size */
|
||||
composite_free, /* free */
|
||||
composite_offset, /* offset */
|
||||
composite_get_ptr, /* get_ptr */
|
||||
composite_memcpy, /* memcpy */
|
||||
NULL, /* find_guint8 XXX */
|
||||
NULL, /* pbrk_guint8 XXX */
|
||||
NULL, /* clone */
|
||||
};
|
||||
|
||||
/*
|
||||
* Composite tvb
|
||||
*
|
||||
* 1. A composite tvb is automatically chained to its first member when the
|
||||
* tvb is finalized.
|
||||
* This means that composite tvb members must all be in the same chain.
|
||||
* ToDo: enforce this: By searching the chain?
|
||||
*/
|
||||
tvbuff_t *
|
||||
tvb_new_composite(void)
|
||||
{
|
||||
tvbuff_t *tvb = tvb_new(&tvb_composite_ops);
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite = &composite_tvb->composite;
|
||||
|
||||
composite->tvbs = NULL;
|
||||
composite->start_offsets = NULL;
|
||||
composite->end_offsets = NULL;
|
||||
|
||||
return tvb;
|
||||
}
|
||||
|
||||
void
|
||||
tvb_composite_append(tvbuff_t *tvb, tvbuff_t *member)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite;
|
||||
|
||||
DISSECTOR_ASSERT(tvb && !tvb->initialized);
|
||||
DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops);
|
||||
|
||||
/* Don't allow zero-length TVBs: composite_memcpy() can't handle them
|
||||
* and anyway it makes no sense.
|
||||
*/
|
||||
DISSECTOR_ASSERT(member->length);
|
||||
|
||||
composite = &composite_tvb->composite;
|
||||
composite->tvbs = g_slist_append(composite->tvbs, member);
|
||||
}
|
||||
|
||||
void
|
||||
tvb_composite_prepend(tvbuff_t *tvb, tvbuff_t *member)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
tvb_comp_t *composite;
|
||||
|
||||
DISSECTOR_ASSERT(tvb && !tvb->initialized);
|
||||
DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops);
|
||||
|
||||
/* Don't allow zero-length TVBs: composite_memcpy() can't handle them
|
||||
* and anyway it makes no sense.
|
||||
*/
|
||||
DISSECTOR_ASSERT(member->length);
|
||||
|
||||
composite = &composite_tvb->composite;
|
||||
composite->tvbs = g_slist_prepend(composite->tvbs, member);
|
||||
}
|
||||
|
||||
void
|
||||
tvb_composite_finalize(tvbuff_t *tvb)
|
||||
{
|
||||
struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
|
||||
GSList *slist;
|
||||
guint num_members;
|
||||
tvbuff_t *member_tvb;
|
||||
tvb_comp_t *composite;
|
||||
int i = 0;
|
||||
|
||||
DISSECTOR_ASSERT(tvb && !tvb->initialized);
|
||||
DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops);
|
||||
DISSECTOR_ASSERT(tvb->length == 0);
|
||||
DISSECTOR_ASSERT(tvb->reported_length == 0);
|
||||
|
||||
composite = &composite_tvb->composite;
|
||||
num_members = g_slist_length(composite->tvbs);
|
||||
|
||||
/* Dissectors should not create composite TVBs if they're not going to
|
||||
* put at least one TVB in them.
|
||||
* (Without this check--or something similar--we'll seg-fault below.)
|
||||
*/
|
||||
DISSECTOR_ASSERT(num_members);
|
||||
|
||||
composite->start_offsets = g_new(guint, num_members);
|
||||
composite->end_offsets = g_new(guint, num_members);
|
||||
|
||||
for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
|
||||
DISSECTOR_ASSERT((guint) i < num_members);
|
||||
member_tvb = (tvbuff_t *)slist->data;
|
||||
composite->start_offsets[i] = tvb->length;
|
||||
tvb->length += member_tvb->length;
|
||||
tvb->reported_length += member_tvb->reported_length;
|
||||
composite->end_offsets[i] = tvb->length - 1;
|
||||
i++;
|
||||
}
|
||||
tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb); /* chain composite tvb to first member */
|
||||
tvb->initialized = TRUE;
|
||||
}
|
Loading…
Reference in New Issue