aboutsummaryrefslogtreecommitdiffstats
path: root/epan/value_string.c
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-03-28 22:02:04 +0000
committerEvan Huus <eapache@gmail.com>2013-03-28 22:02:04 +0000
commit6f19d87f4e3aaa5872bdec1d9f4e50d85eee193d (patch)
tree06c3e5060410fc1de33363d8e0c84fde8a6b19c7 /epan/value_string.c
parent2787c28d71f8ad305325756c3b7aa0a5ed3e84db (diff)
Greatly clean up value_string.c
- use consistent indentation and coding style - add modelines - replace some g_assert calls with DISSECTOR_ASSERT where it makes sense - group related functions together and simplify many comments by referring to the 'normal' value_string as the canonical version svn path=/trunk/; revision=48633
Diffstat (limited to 'epan/value_string.c')
-rw-r--r--epan/value_string.c722
1 files changed, 380 insertions, 342 deletions
diff --git a/epan/value_string.c b/epan/value_string.c
index 762f3ea321..c2b79e0b49 100644
--- a/epan/value_string.c
+++ b/epan/value_string.c
@@ -22,485 +22,446 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
-
#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
-#include "to_str.h"
#include "emem.h"
+#include "proto.h"
+#include "to_str.h"
#include "value_string.h"
-#include <string.h>
-/* --------------------------------------------------------------------*/
+/* REGULAR VALUE STRING */
+
/* Tries to match val against each element in the value_string array vs.
Returns the associated string ptr on a match.
Formats val with fmt, and returns the resulting string, on failure. */
const gchar*
-val_to_str(const guint32 val, const value_string *vs, const char *fmt) {
- const gchar *ret;
+val_to_str(const guint32 val, const value_string *vs, const char *fmt)
+{
+ const gchar *ret;
- g_assert(fmt != NULL);
+ DISSECTOR_ASSERT(fmt != NULL);
- ret = match_strval(val, vs);
- if (ret != NULL)
- return ret;
+ ret = match_strval(val, vs);
+ if (ret != NULL)
+ return ret;
- return ep_strdup_printf(fmt, val);
+ return ep_strdup_printf(fmt, val);
}
-/* --------------------------------------------------------------------*/
/* Tries to match val against each element in the value_string array vs.
Returns the associated string ptr on a match.
Returns 'unknown_str', on failure. */
const gchar*
-val_to_str_const(const guint32 val, const value_string *vs, const char *unknown_str) {
- const gchar *ret;
+val_to_str_const(const guint32 val, const value_string *vs,
+ const char *unknown_str)
+{
+ const gchar *ret;
- g_assert(unknown_str != NULL);
+ DISSECTOR_ASSERT(unknown_str != NULL);
- ret = match_strval(val, vs);
- if (ret != NULL)
- return ret;
+ ret = match_strval(val, vs);
+ if (ret != NULL)
+ return ret;
- return unknown_str;
+ return unknown_str;
}
-/* --------------------------------------------------------------------*/
/* Tries to match val against each element in the value_string array vs.
Returns the associated string ptr, and sets "*idx" to the index in
that table, on a match, and returns NULL, and sets "*idx" to -1,
on failure. */
const gchar*
-match_strval_idx(const guint32 val, const value_string *vs, gint *idx) {
- gint i = 0;
-
- if(vs) {
- while (vs[i].strptr) {
- if (vs[i].value == val) {
- *idx = i;
- return(vs[i].strptr);
- }
- i++;
+match_strval_idx(const guint32 val, const value_string *vs, gint *idx)
+{
+ gint i = 0;
+
+ DISSECTOR_ASSERT(idx != NULL);
+
+ if(vs) {
+ while (vs[i].strptr) {
+ if (vs[i].value == val) {
+ *idx = i;
+ return(vs[i].strptr);
+ }
+ i++;
+ }
}
- }
- *idx = -1;
- return NULL;
+ *idx = -1;
+ return NULL;
}
/* Like match_strval_idx(), but doesn't return the index. */
const gchar*
-match_strval(const guint32 val, const value_string *vs) {
+match_strval(const guint32 val, const value_string *vs)
+{
gint ignore_me;
return match_strval_idx(val, vs, &ignore_me);
}
-/* --------------------------------------------------------------------*/
-/* value_string_ext functions
- *
- * Extended value strings allow fast(er) value_string array lookups by
- * using (if possible) direct access or a binary search of the array.
- *
- * If the values in the value_string array are a contiguous range of values
- * from min to max, the value will be used as as a direct index into the array.
+/* EXTENDED VALUE STRING */
+
+/* Extended value strings allow fast(er) value_string array lookups by
+ * using (if possible) direct access or a binary search of the array.
*
- * If the values in the array are not contiguous (ie: there are "gaps"),
- * but are in assending order a binary search will be used.
+ * If the values in the value_string array are a contiguous range of values
+ * from min to max, the value will be used as as a direct index into the array.
*
- * If direct access or binary search cannot be used, then a linear search
- * is used.
+ * If the values in the array are not contiguous (ie: there are "gaps"),
+ * but are in assending order a binary search will be used.
*
- * Note that the value_string array used with VALUE_STRING_EXT_INIT
- * *must* be terminated with {0, NULL}).
+ * If direct access or binary search cannot be used, then a linear search
+ * is used and a warning is emitted.
*
- * Extended value strings are defined at compile time as follows:
- * static const value_string vs[] = { {value1, "string1"}, {value2, "string2"}, ..., {0, NULL}};
- * static value_string_ext vse = VALUE_STRING_EXT_INIT(vs);
+ * Note that the value_string array used with VALUE_STRING_EXT_INIT
+ * *must* be terminated with {0, NULL}).
*
- * Extended value strings can be created at runtime by calling
- * value_string_ext_new(<ptr to value_string array>,
- * <total number of entries in the value_string_array>,
- * <value_string_name>);
- * Note: <total number of entries in the value_string_array> should include the {0, NULL} entry
+ * Extended value strings are defined at compile time as follows:
+ * static const value_string vs[] = { {value1, "string1"},
+ * {value2, "string2"},
+ * ...,
+ * {0, NULL}};
+ * static value_string_ext vse = VALUE_STRING_EXT_INIT(vs);
*
+ * Extended value strings can be created at runtime by calling
+ * value_string_ext_new(<ptr to value_string array>,
+ * <total number of entries in the value_string_array>,
+ * <value_string_name>);
+ * Note: The <total number of entries in the value_string_array> should include
+ * the {0, NULL} entry.
*/
-/* --------------------------------------------------------------------*/
-
-/* Create a value_string_ext given a ptr to a value_string array and the total number of entries. */
-/* Note: The total number of entries should include the required {0, NULL} terminating entry of the array. */
-/* Return: a pointer to a g_malloc'd and initialized value_string_ext struct. */
+/* Create a value_string_ext given a ptr to a value_string array and the total
+ * number of entries. Note that the total number of entries should include the
+ * required {0, NULL} terminating entry of the array.
+ * Returns a pointer to a g_malloc'd and initialized value_string_ext struct. */
value_string_ext *
-value_string_ext_new(value_string *vs, guint vs_tot_num_entries, const gchar *vs_name) {
+value_string_ext_new(value_string *vs, guint vs_tot_num_entries,
+ const gchar *vs_name)
+{
value_string_ext *vse;
- g_assert (vs_name != NULL);
- g_assert (vs_tot_num_entries > 0);
- g_assert (vs[vs_tot_num_entries-1].strptr == NULL); /* Null-terminated value-string ? */
- vse = (value_string_ext *)g_malloc(sizeof (value_string_ext));
+
+ DISSECTOR_ASSERT (vs_name != NULL);
+ DISSECTOR_ASSERT (vs_tot_num_entries > 0);
+ /* Null-terminated value-string ? */
+ DISSECTOR_ASSERT (vs[vs_tot_num_entries-1].strptr == NULL);
+
+ vse = g_new(value_string_ext, 1);
vse->_vs_p = vs;
- vse->_vs_num_entries = vs_tot_num_entries - 1; /* remember the actual number of entries */
- vse->_vs_first_value = 0; /* initialized in _match_strval_ext_init */
+ vse->_vs_num_entries = vs_tot_num_entries - 1;
+ /* We set our 'match' function to the init function, which finishes by
+ * setting the match function properly and then calling it. This is a
+ * simple way to do lazy initialization of extended value strings.
+ * The init function also sets up _vs_first_value for us. */
+ vse->_vs_first_value = 0;
vse->_vs_match2 = _match_strval_ext_init;
vse->_vs_name = vs_name;
+
return vse;
}
-/* Looks up val in a value_string array using access method (direct, binary search
- * or linear) determined at rutime during the initial access); (see _match_strval_ext_init)
- * Returns the associated string ptr on a match, and returns NULL on failure.
- */
+/* Like match_strval for extended value strings */
const gchar*
-match_strval_ext(const guint32 val, const value_string_ext *vse) {
+match_strval_ext(const guint32 val, const value_string_ext *vse)
+{
if (vse) {
- const value_string *vs = vse->_vs_match2(val, vse);
- if (vs)
- return vs->strptr;
+ const value_string *vs = vse->_vs_match2(val, vse);
+
+ if (vs) {
+ return vs->strptr;
+ }
}
+
return NULL;
}
-/* Tries to match val against each element in the value_string array vs.
- * Returns the associated string ptr, and sets "*idx" to the index in
- * that table, on a match, and returns NULL, and sets "*idx" to -1,
- * on failure.
- */
-
+/* Like match_strval_idx for extended value strings */
const gchar*
-match_strval_idx_ext(const guint32 val, value_string_ext *vse, gint *idx) {
+match_strval_idx_ext(const guint32 val, value_string_ext *vse, gint *idx)
+{
if (vse) {
- const value_string *vs = vse->_vs_match2(val, vse);
- if (vs) {
- *idx = (gint) (vs - vse->_vs_p);
- return vs->strptr;
- }
+ const value_string *vs = vse->_vs_match2(val, vse);
+ if (vs) {
+ *idx = (gint) (vs - vse->_vs_p);
+ return vs->strptr;
+ }
}
*idx = -1;
return NULL;
}
-/* Similar to match_strval_ext except that on failure
- * Formats val with fmt, and returns the resulting string
- */
+/* Like val_to_str for extended value strings */
const gchar*
-val_to_str_ext(const guint32 val, const value_string_ext *vse, const char *fmt) {
- const gchar *ret;
+val_to_str_ext(const guint32 val, const value_string_ext *vse, const char *fmt)
+{
+ const gchar *ret;
- g_assert(fmt != NULL);
+ DISSECTOR_ASSERT(fmt != NULL);
- ret = match_strval_ext(val, vse);
- if (ret != NULL)
- return ret;
+ ret = match_strval_ext(val, vse);
+ if (ret != NULL)
+ return ret;
- return ep_strdup_printf(fmt, val);
+ return ep_strdup_printf(fmt, val);
}
-/* Similar to match_strval_ext except that on failure
- * Returns 'unknown_str'
- */
+/* Like val_to_str_const for extended value strings */
const gchar*
-val_to_str_ext_const(const guint32 val, const value_string_ext *vse, const char *unknown_str) {
- const gchar *ret;
+val_to_str_ext_const(const guint32 val, const value_string_ext *vse,
+ const char *unknown_str)
+{
+ const gchar *ret;
- g_assert(unknown_str != NULL);
+ DISSECTOR_ASSERT(unknown_str != NULL);
- ret = match_strval_ext(val, vse);
- if (ret != NULL)
- return ret;
+ ret = match_strval_ext(val, vse);
+ if (ret != NULL)
+ return ret;
- return unknown_str;
+ return unknown_str;
}
+/* Fallback linear matching algorithm for extended value strings */
static const value_string *
_match_strval_linear(const guint32 val, const value_string_ext *vse)
{
- const value_string *vs_p = vse->_vs_p;
- guint i;
- for (i=0; i<vse->_vs_num_entries; i++) {
- if (vs_p[i].value == val)
- return &(vs_p[i]);
- }
- return NULL;
+ const value_string *vs_p = vse->_vs_p;
+ guint i;
+ for (i=0; i<vse->_vs_num_entries; i++) {
+ if (vs_p[i].value == val)
+ return &(vs_p[i]);
+ }
+ return NULL;
}
+/* Constant-time matching algorithm for contiguous extended value strings */
static const value_string *
_match_strval_index(const guint32 val, const value_string_ext *vse)
{
- guint i;
-
- i = val - vse->_vs_first_value;
- if (i < vse->_vs_num_entries) {
- g_assert (val == vse->_vs_p[i].value);
- return &(vse->_vs_p[i]);
- }
- return NULL;
+ guint i;
+
+ i = val - vse->_vs_first_value;
+ if (i < vse->_vs_num_entries) {
+ g_assert (val == vse->_vs_p[i].value);
+ return &(vse->_vs_p[i]);
+ }
+ return NULL;
}
+/* log(n)-time matching algorithm for sorted extended value strings */
static const value_string *
_match_strval_bsearch(const guint32 val, const value_string_ext *vse)
{
- guint low, i, max;
- guint32 item;
-
- for (low = 0, max = vse->_vs_num_entries; low < max; ) {
- i = (low + max) / 2;
- item = vse->_vs_p[i].value;
-
- if (val < item)
- max = i;
- else if (val > item)
- low = i + 1;
- else
- return &(vse->_vs_p[i]);
- }
- return NULL;
+ guint low, i, max;
+ guint32 item;
+
+ for (low = 0, max = vse->_vs_num_entries; low < max; ) {
+ i = (low + max) / 2;
+ item = vse->_vs_p[i].value;
+
+ if (val < item)
+ max = i;
+ else if (val > item)
+ low = i + 1;
+ else
+ return &(vse->_vs_p[i]);
+ }
+ return NULL;
}
-/* Init value_string_ext struct
- - Go thru the value_string array to determine whether indexed access
- or binary search access is possible;
- - Verify that the value_string array does not contain any
- NULL string pointers;
- - Verify that the value_string array is terminated
- by {0, NULL};
-*/
+/* Initializes an extended value string. Behaves like a match function to
+ * permit lazy initialization of extended value strings.
+ * - Goes through the value_string array to determine the fastest possible
+ * access method.
+ * - Verifies that the value_string contains no NULL string pointers.
+ * - Verifies that the value_string is terminated by {0, NULL}
+ */
const value_string *
_match_strval_ext_init(const guint32 val, const value_string_ext *a_vse)
{
- /* Cast away the constness!
- * It's better if the prototype for this function matches the other
- * _match_strval_* functions (so we don't have to cast it when storing it
- * in _match_strval so the compiler will notice if the prototypes get out
- * of sync), but the init function is unique in that it does actually
- * modify the vse.
- */
- value_string_ext *vse = (value_string_ext *)a_vse;
-
- const value_string *vs_p = vse->_vs_p;
- const guint vs_num_entries = vse->_vs_num_entries;
-
-/* The way matching of value is done in a value_string:
- * 0 Sequential search (as in a normal value string)
- * 1 Binary search, the values MUST be in numerical order.
- * 2 The value used as an index(the value string MUST have all values between first and last defined in numerical order)
- */
-
-/* Note: The value_string 'value' is *unsigned*.
- *
- * Special case:
- * { -3, -2, -1, 0, 1, 2 } will be treated as "ascending ordered" (altho not really such)
- * thus allowing as a 'direct' search.
- *
- * Note:
- * { -3, -2, 0, 1, 2 } and { -3, -2, -1, 0, 2 } will both be considered as "out-of-order with gaps"
- * thus requiring a 'linear' search.
- * { 0, 1, 2, -3, -2 } and { 0, 2, -3, -2, -1 } will be considered "ascending ordered with gaps"
- * thus allowing a 'binary' search.
- */
-
- enum { VS_SEARCH = 0, VS_BIN_TREE, VS_INDEX } type = VS_INDEX;
-
- guint32 prev_value;
- guint first_value;
- guint i;
-
- g_assert((vs_p[vs_num_entries].value==0) && (vs_p[vs_num_entries].strptr==NULL));
-
- vse->_vs_first_value = vs_p[0].value;
- first_value = vs_p[0].value;
- prev_value = first_value;
-
- for (i = 0; i < vs_num_entries; i++) {
- g_assert(vs_p[i].strptr != NULL);
- if ((type == VS_INDEX) && (vs_p[i].value != (i + first_value))) {
- type = VS_BIN_TREE;
- }
- /* XXX: Should check for dups ?? */
- if (type == VS_BIN_TREE) {
- if (prev_value > vs_p[i].value) {
- g_warning("Extended value string %s forced to fall back to linear search: entry %u, value %u < previous entry, value %u",
- vse->_vs_name, i, vs_p[i].value, prev_value);
- type = VS_SEARCH;
- break;
- }
- if (first_value > vs_p[i].value) {
- g_warning("Extended value string %s forced to fall back to linear search: entry %u, value %u < first entry, value %u",
- vse->_vs_name, i, vs_p[i].value, first_value);
- type = VS_SEARCH;
- break;
- }
+ /* Cast away the constness!
+ * It's better if the prototype for this function matches the other
+ * _match_strval_* functions (so we don't have to cast it when storing it
+ * in _match_strval so the compiler will notice if the prototypes get out
+ * of sync), but the init function is unique in that it does actually
+ * modify the vse.
+ */
+ value_string_ext *vse = (value_string_ext *)a_vse;
+
+ const value_string *vs_p = vse->_vs_p;
+ const guint vs_num_entries = vse->_vs_num_entries;
+
+ /* The matching algorithm used:
+ * VS_SEARCH - slow sequential search (as in a normal value string)
+ * VS_BIN_TREE - log(n)-time binary search, the values must be sorted
+ * VS_INDEX - constant-time index lookup, the values must be contiguous
+ */
+ enum { VS_SEARCH, VS_BIN_TREE, VS_INDEX } type = VS_INDEX;
+
+ /* Note: The value_string 'value' is *unsigned*, but we do a little magic
+ * to help with value strings that have negative values.
+ *
+ * { -3, -2, -1, 0, 1, 2 }
+ * will be treated as "ascending ordered" (although it isn't technically),
+ * thus allowing constant-time index search
+ *
+ * { -3, -2, 0, 1, 2 } and { -3, -2, -1, 0, 2 }
+ * will both be considered as "out-of-order with gaps", thus falling
+ * back to the slow linear search
+ *
+ * { 0, 1, 2, -3, -2 } and { 0, 2, -3, -2, -1 }
+ * will be considered "ascending ordered with gaps" thus allowing
+ * a log(n)-time 'binary' search
+ *
+ * If you're confused, think of how negative values are represented, or
+ * google two's complement.
+ */
+
+ guint32 prev_value;
+ guint first_value;
+ guint i;
+
+ DISSECTOR_ASSERT((vs_p[vs_num_entries].value == 0) &&
+ (vs_p[vs_num_entries].strptr == NULL));
+
+ vse->_vs_first_value = vs_p[0].value;
+ first_value = vs_p[0].value;
+ prev_value = first_value;
+
+ for (i = 0; i < vs_num_entries; i++) {
+ DISSECTOR_ASSERT(vs_p[i].strptr != NULL);
+ if ((type == VS_INDEX) && (vs_p[i].value != (i + first_value))) {
+ type = VS_BIN_TREE;
+ }
+ /* XXX: Should check for dups ?? */
+ if (type == VS_BIN_TREE) {
+ if (prev_value > vs_p[i].value) {
+ g_warning("Extended value string %s forced to fall back to linear search: entry %u, value %u < previous entry, value %u",
+ vse->_vs_name, i, vs_p[i].value, prev_value);
+ type = VS_SEARCH;
+ break;
+ }
+ if (first_value > vs_p[i].value) {
+ g_warning("Extended value string %s forced to fall back to linear search: entry %u, value %u < first entry, value %u",
+ vse->_vs_name, i, vs_p[i].value, first_value);
+ type = VS_SEARCH;
+ break;
+ }
+ }
+
+ prev_value = vs_p[i].value;
}
- prev_value = vs_p[i].value;
- }
-
- switch (type) {
- case VS_SEARCH:
- vse->_vs_match2 = _match_strval_linear;
- break;
- case VS_BIN_TREE:
- vse->_vs_match2 = _match_strval_bsearch;
- break;
- case VS_INDEX:
- vse->_vs_match2 = _match_strval_index;
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- return vse->_vs_match2(val, vse);
-}
+ switch (type) {
+ case VS_SEARCH:
+ vse->_vs_match2 = _match_strval_linear;
+ break;
+ case VS_BIN_TREE:
+ vse->_vs_match2 = _match_strval_bsearch;
+ break;
+ case VS_INDEX:
+ vse->_vs_match2 = _match_strval_index;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
-/* (Fcns for use by proto_registrar_dump_values() [See proto.c]) */
-gboolean
-value_string_ext_validate(const value_string_ext *vse) {
- if (vse == NULL)
- return FALSE;
- if ((vse->_vs_match2 == _match_strval_ext_init) ||
- (vse->_vs_match2 == _match_strval_linear) ||
- (vse->_vs_match2 == _match_strval_bsearch) ||
- (vse->_vs_match2 == _match_strval_index))
- return TRUE;
- return FALSE;
+ return vse->_vs_match2(val, vse);
}
-const gchar *
-value_string_ext_match_type_str(const value_string_ext *vse) {
- if (vse->_vs_match2 == _match_strval_linear)
- return "[Linear Search]";
- if (vse->_vs_match2 == _match_strval_bsearch)
- return "[Binary Search]";
- if (vse->_vs_match2 == _match_strval_index)
- return "[Direct (indexed) Access]";
- return "[Match Type not initialized or invalid]";
-}
+/* STRING TO STRING MATCHING */
-/* ----------- */
+/* string_string is like value_string except the values being matched are
+ * also strings (instead of unsigned integers) */
-/* Tries to match val against each element in the value_string array vs.
- Returns the associated string ptr on a match.
- Formats val with fmt, and returns the resulting string, on failure. */
+/* Like val_to_str except for string_string */
const gchar*
-str_to_str(const gchar *val, const string_string *vs, const char *fmt) {
- const gchar *ret;
+str_to_str(const gchar *val, const string_string *vs, const char *fmt)
+{
+ const gchar *ret;
- g_assert(fmt != NULL);
+ DISSECTOR_ASSERT(fmt != NULL);
- ret = match_strstr(val, vs);
- if (ret != NULL)
- return ret;
+ ret = match_strstr(val, vs);
+ if (ret != NULL)
+ return ret;
- return ep_strdup_printf(fmt, val);
+ return ep_strdup_printf(fmt, val);
}
-/* Tries to match val against each element in the value_string array vs.
- Returns the associated string ptr, and sets "*idx" to the index in
- that table, on a match, and returns NULL, and sets "*idx" to -1,
- on failure. */
+/* Like match_strval_idx except for string_string */
const gchar*
-match_strstr_idx(const gchar *val, const string_string *vs, gint *idx) {
- gint i = 0;
-
- if(vs) {
- while (vs[i].strptr) {
- if (!strcmp(vs[i].value,val)) {
- *idx = i;
- return(vs[i].strptr);
- }
- i++;
+match_strstr_idx(const gchar *val, const string_string *vs, gint *idx)
+{
+ gint i = 0;
+
+ if(vs) {
+ while (vs[i].strptr) {
+ if (!strcmp(vs[i].value,val)) {
+ *idx = i;
+ return(vs[i].strptr);
+ }
+ i++;
+ }
}
- }
- *idx = -1;
- return NULL;
+ *idx = -1;
+ return NULL;
}
-/* Like match_strval_idx(), but doesn't return the index. */
+/* Like match_strval except for string_string */
const gchar*
-match_strstr(const gchar *val, const string_string *vs) {
+match_strstr(const gchar *val, const string_string *vs)
+{
gint ignore_me;
return match_strstr_idx(val, vs, &ignore_me);
}
-/* Generate a string describing an enumerated bitfield (an N-bit field
- with various specific values having particular names). */
-const char *
-decode_enumerated_bitfield(const guint32 val, const guint32 mask, const int width,
- const value_string *tab, const char *fmt)
-{
- static char buf[1025];
- char *p;
-
- p = decode_bitfield_value(buf, val, mask, width);
- g_snprintf(p, (gulong) (1024-(p-buf)), fmt, val_to_str_const(val & mask, tab, "Unknown"));
- return buf;
-}
-
-
-/* Generate a string describing an enumerated bitfield (an N-bit field
- with various specific values having particular names). */
-const char *
-decode_enumerated_bitfield_shifted(const guint32 val, const guint32 mask, const int width,
- const value_string *tab, const char *fmt)
-{
- static char buf[1025];
- char *p;
- int shift = 0;
-
- /* Compute the number of bits we have to shift the bitfield right
- to extract its value. */
- while ((mask & (1<<shift)) == 0)
- shift++;
-
- p = decode_bitfield_value(buf, val, mask, width);
- g_snprintf(p, (gulong) (1024-(p-buf)), fmt, val_to_str_const((val & mask) >> shift, tab, "Unknown"));
- return buf;
-}
+/* RANGE TO STRING MATCHING */
+/* range_string is like value_string except the values being matched are
+ * integer ranges (for example, 0-10, 11-19, etc.) instead of single values. */
-/* FF: ranges aware versions */
-
-/* Tries to match val against each range in the range_string array rs.
- Returns the associated string ptr on a match.
- Formats val with fmt, and returns the resulting string, on failure. */
+/* Like val_to_str except for range_string */
const gchar *
rval_to_str(const guint32 val, const range_string *rs, const char *fmt)
{
- const gchar *ret = NULL;
+ const gchar *ret = NULL;
- g_assert(fmt != NULL);
+ DISSECTOR_ASSERT(fmt != NULL);
- ret = match_strrval(val, rs);
- if(ret != NULL)
- return ret;
+ ret = match_strrval(val, rs);
+ if(ret != NULL)
+ return ret;
- return ep_strdup_printf(fmt, val);
+ return ep_strdup_printf(fmt, val);
}
-/* Tries to match val against each range in the range_string array rs.
- Returns the associated string ptr, and sets "*idx" to the index in
- that table, on a match, and returns NULL, and sets "*idx" to -1,
- on failure. */
+/* Like match_strval_idx except for range_string */
const gchar *
match_strrval_idx(const guint32 val, const range_string *rs, gint *idx)
{
- gint i = 0;
-
- if(rs) {
- while(rs[i].strptr) {
- if( (val >= rs[i].value_min) && (val <= rs[i].value_max) ) {
- *idx = i;
- return (rs[i].strptr);
- }
- i++;
+ gint i = 0;
+
+ if(rs) {
+ while(rs[i].strptr) {
+ if( (val >= rs[i].value_min) && (val <= rs[i].value_max) ) {
+ *idx = i;
+ return (rs[i].strptr);
+ }
+ i++;
+ }
}
- }
- *idx = -1;
- return NULL;
+ *idx = -1;
+ return NULL;
}
-/* Like match_strrval_idx(), but doesn't return the index. */
+/* Like match_strval except for range_string */
const gchar *
match_strrval(const guint32 val, const range_string *rs)
{
@@ -508,3 +469,80 @@ match_strrval(const guint32 val, const range_string *rs)
return match_strrval_idx(val, rs, &ignore_me);
}
+/* MISC */
+
+/* Functions for use by proto_registrar_dump_values(), see proto.c */
+
+gboolean
+value_string_ext_validate(const value_string_ext *vse)
+{
+ if (vse == NULL)
+ return FALSE;
+ if ((vse->_vs_match2 == _match_strval_ext_init) ||
+ (vse->_vs_match2 == _match_strval_linear) ||
+ (vse->_vs_match2 == _match_strval_bsearch) ||
+ (vse->_vs_match2 == _match_strval_index))
+ return TRUE;
+ return FALSE;
+}
+
+const gchar *
+value_string_ext_match_type_str(const value_string_ext *vse)
+{
+ if (vse->_vs_match2 == _match_strval_linear)
+ return "[Linear Search]";
+ if (vse->_vs_match2 == _match_strval_bsearch)
+ return "[Binary Search]";
+ if (vse->_vs_match2 == _match_strval_index)
+ return "[Direct (indexed) Access]";
+ return "[Match Type not initialized or invalid]";
+}
+
+/* Functions for bitfield generation, do they even belong here? */
+
+/* Generate a string describing an enumerated bitfield (an N-bit field
+ with various specific values having particular names). */
+const char *
+decode_enumerated_bitfield(const guint32 val, const guint32 mask,
+ const int width, const value_string *tab, const char *fmt)
+{
+ static char buf[1025];
+ char *p;
+
+ p = decode_bitfield_value(buf, val, mask, width);
+ g_snprintf(p, (gulong) (1024-(p-buf)), fmt, val_to_str_const(val & mask, tab, "Unknown"));
+ return buf;
+}
+
+/* Generate a string describing an enumerated bitfield (an N-bit field
+ with various specific values having particular names). */
+const char *
+decode_enumerated_bitfield_shifted(const guint32 val, const guint32 mask,
+ const int width, const value_string *tab, const char *fmt)
+{
+ static char buf[1025];
+ char *p;
+ int shift = 0;
+
+ /* Compute the number of bits we have to shift the bitfield right
+ to extract its value. */
+ while ((mask & (1<<shift)) == 0)
+ shift++;
+
+ p = decode_bitfield_value(buf, val, mask, width);
+ g_snprintf(p, (gulong) (1024-(p-buf)), fmt, val_to_str_const((val & mask) >> shift, tab, "Unknown"));
+ return buf;
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */