aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff.h
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2011-12-21 17:39:02 +0000
committerBill Meier <wmeier@newsguy.com>2011-12-21 17:39:02 +0000
commit14309d2c72fd3014f37816d939cd80fe79ff7406 (patch)
tree2999ffae3fc67e08f1774c122e76ffe58eb958aa /epan/tvbuff.h
parentff30e7df577940b8729c36b7a8952e9bcd5c7e88 (diff)
A simplified version of tvbuffs:
- Essentially no changes from current dissector de facto tvbuff usage; - Do away with 'usage_counts' and with 'used_in' GSLists; - Manage tvb chains via a simple doubly linked list. - API changes: a. tvb_increment_usage_count() and tvb_decrement_usage_count() no longer exist; b. tvb_free_chain() can only be called for the 'top-level' (initial) tvb of a chain) or for a tvb not in a chain. c. tvb_free() now just calls tvb_free_chain() [should have no impact on existing dissectors]. svn path=/trunk/; revision=40264
Diffstat (limited to 'epan/tvbuff.h')
-rw-r--r--epan/tvbuff.h97
1 files changed, 52 insertions, 45 deletions
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
index 1d3415a5df..61b7b12c30 100644
--- a/epan/tvbuff.h
+++ b/epan/tvbuff.h
@@ -50,7 +50,6 @@
* virtual data.
*/
-
/** The different types of tvbuff's */
typedef enum {
TVBUFF_REAL_DATA,
@@ -61,6 +60,30 @@ typedef enum {
struct tvbuff;
typedef struct tvbuff tvbuff_t;
+/**
+ * tvbuffs: dissector use and management
+ *
+ * Consider a collection of tvbs as being a chain or stack of tvbs.
+ *
+ * The top-level dissector (packet.c) pushes the initial tvb onto the stack
+ * (starts the chain) and then calls a sub-dissector which in turn calls the next
+ * sub-dissector and so on. Each sub-dissector may chain additional tvbs to
+ * the tvb handed to that dissector. After dissection is complete and control has
+ * returned to the top-level dissector, the chain of tvbs (stack) is free'd
+ * via a call to tvb_free_chain() (in epan_dissect_cleanup()).
+ *
+ * A dissector:
+ * - Can chain new tvbs (real, subset, composite) to the tvb
+ * handed to the dissector via tvb_subset(), tvb_new_child_real_data(), etc.
+ * (Subset and Composite tvbs should reference only tvbs which are
+ * already part of the chain).
+ * - Must not save a pointer to a tvb handed to the dissector for
+ * use when dissecting another frame; A higher level function
+ * may very well free the chain). This also applies to any tvbs chained
+ * by the dissector to the tvb handed to the dissector.
+ * - Can create its own tvb chain (using tvb_new_real_data() which
+ * the dissector is free to manage as desired. */
+
/** TVBUFF_REAL_DATA contains a guint8* that points to real data.
* The data is allocated and contiguous.
*
@@ -77,63 +100,44 @@ typedef struct tvbuff tvbuff_t;
* Once a tvbuff is create/initialized/finalized, the tvbuff is read-only.
* That is, it cannot point to any other data. A new tvbuff must be created if
* you want a tvbuff that points to other data.
+ *
+ * tvbuff's are normally chained together to allow efficient de-allocation of tvbuff's.
+ *
*/
typedef void (*tvbuff_free_cb_t)(void*);
/** Returns a pointer to a newly initialized tvbuff. Note that
* tvbuff's of types TVBUFF_SUBSET and TVBUFF_COMPOSITE
- * require further initialization via the appropriate functions */
+ * require further initialization via the appropriate functions. */
extern tvbuff_t* tvb_new(tvbuff_type);
-/** Extracs from bit offset number of bits and
- * Returns a pointer to a newly initialized tvbuff. with the bits
- * octet aligned.
+/** 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.
*/
extern tvbuff_t* tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits);
-
-/** Marks a tvbuff for freeing. The guint8* data of a TVBUFF_REAL_DATA
- * is *never* freed by the tvbuff routines. The tvbuff itself is actually freed
- * once its usage count drops to 0.
- *
- * Usage counts increment for any time the tvbuff is
- * used as a member of another tvbuff, i.e., as the backing buffer for
- * a TVBUFF_SUBSET or as a member of a TVBUFF_COMPOSITE.
- *
- * Although you may call tvb_free(), the tvbuff may still be in use
- * by other tvbuff's (TVBUFF_SUBSET or TVBUFF_COMPOSITE), so it is not
- * safe, unless you know otherwise, to free your guint8* data. If you
- * cannot be sure that your TVBUFF_REAL_DATA is not in use by another
- * tvbuff, register a callback with tvb_set_free_cb(); when your tvbuff
- * is _really_ freed, then your callback will be called, and at that time
- * you can free your original data.
- *
- * The caller can artificially increment/decrement the usage count
- * with tvbuff_increment_usage_count()/tvbuff_decrement_usage_count().
- */
+/** 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.
+ * If specified, a callback to free the tvbuff data will be invoked
+ * for each tvbuff free'd */
extern void tvb_free(tvbuff_t*);
-/** Free the tvbuff_t and all tvbuff's created from it. */
+/** Free the 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.
+ * If specified, a callback to free the tvbuff data will be invoked
+ * for each tvbuff free'd */
extern void tvb_free_chain(tvbuff_t*);
-/** Both return the new usage count, after the increment or decrement */
-extern guint tvb_increment_usage_count(tvbuff_t*, const guint count);
-
-/** If a decrement causes the usage count to drop to 0, a the tvbuff
- * is immediately freed. Be sure you know exactly what you're doing
- * if you decide to use this function, as another tvbuff could
- * still have a pointer to the just-freed tvbuff, causing corrupted data
- * or a segfault in the future */
-extern guint tvb_decrement_usage_count(tvbuff_t*, const guint count);
-
/** Set a callback function to call when a tvbuff is actually freed
- * (once the usage count drops to 0). One argument is passed to
- * that callback --- a void* that points to the real data.
- * Obviously, this only applies to a TVBUFF_REAL_DATA tvbuff. */
+ * One argument is passed to that callback --- a void* that points
+ * to the real data. Obviously, this only applies to a
+ * TVBUFF_REAL_DATA tvbuff. */
extern void tvb_set_free_cb(tvbuff_t*, const tvbuff_free_cb_t);
-
/** Attach a TVBUFF_REAL_DATA tvbuff to a parent tvbuff. This connection
* is used during a tvb_free_chain()... the "child" TVBUFF_REAL_DATA acts
* as if is part of the chain-of-creation of the parent tvbuff, although it
@@ -141,22 +145,24 @@ extern void tvb_set_free_cb(tvbuff_t*, const tvbuff_free_cb_t);
* run some operation on it, like decryption or decompression, and make a new
* tvbuff from it, yet want the new tvbuff to be part of the chain. The reality
* is that the new tvbuff *is* part of the "chain of creation", but in a way
- * that these tvbuff routines is ignorant of. Use this function to make
+ * that these tvbuff routines are ignorant of. Use this function to make
* the tvbuff routines knowledgable of this fact. */
extern void tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child);
extern tvbuff_t* tvb_new_child_real_data(tvbuff_t* parent, const guint8* data, const guint length,
const gint reported_length);
-/**Sets parameters for TVBUFF_REAL_DATA. Can throw ReportedBoundsError. */
+/** Sets parameters for TVBUFF_REAL_DATA. Can throw ReportedBoundsError. */
extern void tvb_set_real_data(tvbuff_t*, const guint8* data, const guint length,
const gint reported_length);
-/** Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError. */
+/** Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError.
+ * Normally, a callback to free the data should be registered using tvb_set_free_cb();
+ * when this tvbuff is freed, then your callback will be called, and at that time
+ * you can free your original data. */
extern tvbuff_t* tvb_new_real_data(const guint8* data, const guint length,
const gint reported_length);
-
/** Define the subset of the backing buffer to use.
*
* 'backing_offset' can be negative, to indicate bytes from
@@ -291,7 +297,8 @@ extern guint16 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, const gint no_of_b
extern guint32 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const guint encoding);
extern guint64 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const guint encoding);
-/* Fetch a specified number of bits from bit offset in a tvb, but allow number
+/**
+ * Fetch a specified number of bits from bit offset in a tvb, but allow number
* of bits to range between 1 and 32. If the requested number of bits is known
* beforehand, or its range can be handled by a single function of the group
* above, use one of them instead.