diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/tvbuff-int.h | 3 | ||||
-rw-r--r-- | epan/tvbuff.c | 42 | ||||
-rw-r--r-- | epan/tvbuff.h | 8 |
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. |