3 * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "tvbuff-int.h"
28 #include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
29 #include "exceptions.h"
32 /** The backing tvbuff_t */
35 /** The offset of 'tvb' to which I'm privy */
37 /** The length of 'tvb' to which I'm privy */
49 subset_offset(const tvbuff_t *tvb, const guint counter)
51 const struct tvb_subset *subset_tvb = (const struct tvb_subset *) tvb;
52 const tvbuff_t *member = subset_tvb->subset.tvb;
54 return tvb_offset_from_real_beginning_counter(member, counter + subset_tvb->subset.offset);
58 subset_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length)
60 struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
62 return tvb_memcpy(subset_tvb->subset.tvb, target, subset_tvb->subset.offset + abs_offset, abs_length);
66 subset_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
68 struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
70 return tvb_get_ptr(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, abs_length);
74 subset_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
76 struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
78 return tvb_find_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needle);
82 subset_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
84 struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
86 return tvb_ws_mempbrk_pattern_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, pattern, found_needle);
90 subset_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
92 struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
94 return tvb_clone_offset_len(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, abs_length);
97 static const struct tvb_ops tvb_subset_ops = {
98 sizeof(struct tvb_subset), /* size */
101 subset_offset, /* offset */
102 subset_get_ptr, /* get_ptr */
103 subset_memcpy, /* memcpy */
104 subset_find_guint8, /* find_guint8 */
105 subset_pbrk_guint8, /* pbrk_guint8 */
106 subset_clone, /* clone */
110 tvb_new_with_subset(tvbuff_t *backing, const gint reported_length,
111 const guint subset_tvb_offset, const guint subset_tvb_length)
113 tvbuff_t *tvb = tvb_new(&tvb_subset_ops);
114 struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;
116 subset_tvb->subset.offset = subset_tvb_offset;
117 subset_tvb->subset.length = subset_tvb_length;
119 subset_tvb->subset.tvb = backing;
120 tvb->length = subset_tvb_length;
121 tvb->flags = backing->flags;
123 if (reported_length == -1) {
124 tvb->reported_length = backing->reported_length - subset_tvb_offset;
127 tvb->reported_length = reported_length;
129 tvb->initialized = TRUE;
131 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
132 * then we can point directly to our starting offset in that buffer */
133 if (backing->real_data != NULL) {
134 tvb->real_data = backing->real_data + subset_tvb_offset;
138 * The top-level data source of this tvbuff is the top-level
139 * data source of its parent.
141 tvb->ds_tvb = backing->ds_tvb;
147 tvb_new_subset_length_caplen(tvbuff_t *backing, const gint backing_offset, const gint backing_length, const gint reported_length)
150 guint subset_tvb_offset;
151 guint subset_tvb_length;
153 DISSECTOR_ASSERT(backing && backing->initialized);
155 THROW_ON(reported_length < -1, ReportedBoundsError);
157 tvb_check_offset_length(backing, backing_offset, backing_length,
161 tvb = tvb_new_with_subset(backing, reported_length,
162 subset_tvb_offset, subset_tvb_length);
164 tvb_add_to_chain(backing, tvb);
170 tvb_new_subset_length(tvbuff_t *backing, const gint backing_offset, const gint backing_length)
172 gint captured_length;
174 guint subset_tvb_offset;
175 guint subset_tvb_length;
177 DISSECTOR_ASSERT(backing && backing->initialized);
179 THROW_ON(backing_length < 0, ReportedBoundsError);
182 * Give the next dissector only captured_length bytes.
184 captured_length = tvb_captured_length_remaining(backing, backing_offset);
185 THROW_ON(captured_length < 0, BoundsError);
186 if (captured_length > backing_length)
187 captured_length = backing_length;
189 tvb_check_offset_length(backing, backing_offset, captured_length,
193 tvb = tvb_new_with_subset(backing, backing_length,
194 subset_tvb_offset, subset_tvb_length);
196 tvb_add_to_chain(backing, tvb);
202 tvb_new_subset_remaining(tvbuff_t *backing, const gint backing_offset)
205 guint subset_tvb_offset;
206 guint subset_tvb_length;
208 tvb_check_offset_length(backing, backing_offset, -1 /* backing_length */,
212 tvb = tvb_new_with_subset(backing, -1 /* reported_length */,
213 subset_tvb_offset, subset_tvb_length);
215 tvb_add_to_chain(backing, tvb);
221 tvb_new_proxy(tvbuff_t *backing)
226 tvb = tvb_new_with_subset(backing, backing->reported_length, 0, backing->length);
228 tvb = tvb_new_real_data(NULL, 0, 0);
237 * Editor modelines - http://www.wireshark.org/tools/modelines.html
242 * indent-tabs-mode: t
245 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
246 * :indentSize=8:tabSize=8:noTabs=false: