aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/tvbuff-int.h3
-rw-r--r--epan/tvbuff.c42
-rw-r--r--epan/tvbuff.h8
3 files changed, 49 insertions, 4 deletions
diff --git a/epan/tvbuff-int.h b/epan/tvbuff-int.h
index 2aee4c16a2..d8d4cba314 100644
--- a/epan/tvbuff-int.h
+++ b/epan/tvbuff-int.h
@@ -37,6 +37,8 @@ struct tvb_ops {
gint (*tvb_find_guint8)(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle);
gint (*tvb_pbrk_guint8)(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle);
+
+ tvbuff_t *(*tvb_clone)(tvbuff_t *tvb, guint abs_offset, guint abs_length);
};
typedef struct {
@@ -114,5 +116,6 @@ struct tvb_composite {
tvb_comp_t composite;
};
+WS_DLL_PUBLIC tvbuff_t *tvb_new(const struct tvb_ops *ops);
#endif
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index 91701a801f..6de6b7df35 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -629,7 +629,40 @@ tvb_composite_finalize(tvbuff_t *tvb)
tvb->initialized = TRUE;
}
+static tvbuff_t *
+tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
+{
+ tvbuff_t *cloned_tvb;
+
+ guint8 *data = (guint8 *) g_malloc(len);
+
+ tvb_memcpy(tvb, data, offset, len);
+
+ cloned_tvb = tvb_new_real_data(data, len, len);
+ tvb_set_free_cb(cloned_tvb, g_free);
+
+ return cloned_tvb;
+}
+
+tvbuff_t *
+tvb_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
+{
+ if (tvb->ops->tvb_clone) {
+ tvbuff_t *cloned_tvb;
+
+ cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
+ if (cloned_tvb)
+ return cloned_tvb;
+ }
+
+ return tvb_generic_clone_offset_len(tvb, offset, len);
+}
+tvbuff_t *
+tvb_clone(tvbuff_t *tvb)
+{
+ return tvb_clone_offset_len(tvb, 0, tvb->length);
+}
guint
tvb_length(const tvbuff_t *tvb)
@@ -2000,6 +2033,12 @@ subset_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *n
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.
*
@@ -3645,6 +3684,7 @@ static const struct tvb_ops tvb_real_ops = {
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; }
@@ -3657,6 +3697,7 @@ static const struct tvb_ops tvb_subset_ops = {
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; }
@@ -3669,6 +3710,7 @@ static const struct tvb_ops tvb_composite_ops = {
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; }
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
index 7a851112df..144e8c9b1a 100644
--- a/epan/tvbuff.h
+++ b/epan/tvbuff.h
@@ -57,8 +57,6 @@ extern "C" {
struct tvbuff;
typedef struct tvbuff tvbuff_t;
-struct tvb_ops;
-
/** @defgroup tvbuff Testy, Virtual(-izable) Buffers
*
* Dissector use and management
@@ -115,14 +113,16 @@ struct tvb_ops;
typedef void (*tvbuff_free_cb_t)(void*);
-WS_DLL_PUBLIC tvbuff_t *tvb_new(const struct tvb_ops *ops);
-
/** Extracts 'number of bits' starting at 'bit offset'.
* Returns a pointer to a newly initialized ep_alloc'd REAL_DATA
* tvbuff with the bits octet aligned.
*/
WS_DLL_PUBLIC tvbuff_t* tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits);
+WS_DLL_PUBLIC tvbuff_t *tvb_clone(tvbuff_t *tvb);
+
+WS_DLL_PUBLIC tvbuff_t *tvb_clone_offset_len(tvbuff_t *tvb, guint offset, guint len);
+
/** Free a tvbuff_t and all tvbuffs chained from it
* The tvbuff must be 'the 'head' (initial) tvb of a chain or
* must not be in a chain.