forked from osmocom/wireshark
Add support for extended 64 bit value to string matching
This adds val64_string_ext to parallel value_string_ext in the same way that val64_string parallels value_string. Change-Id: Iadbfc49f5a4540000ed92fd0469e8d273911e97e Reviewed-on: https://code.wireshark.org/review/30385 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
81dc105402
commit
99c62bf797
|
@ -1008,6 +1008,25 @@ macro for the 'strings' field in the header_field_info struct array,
|
||||||
|
|
||||||
BASE_SPECIAL_VALS can also be used for val64_string.
|
BASE_SPECIAL_VALS can also be used for val64_string.
|
||||||
|
|
||||||
|
-- val64_string_ext
|
||||||
|
|
||||||
|
val64_string_ext is like value_string_ext, except that the integer type
|
||||||
|
used is a guint64 (instead of guint32).
|
||||||
|
|
||||||
|
Use this macro to initialize the extended val64_string at compile time:
|
||||||
|
|
||||||
|
static val64_string_ext val64stringname_ext = VAL64_STRING_EXT_INIT(val64stringname);
|
||||||
|
|
||||||
|
Extended val64 strings can be created at run time by calling
|
||||||
|
val64_string_ext_new(<ptr to val64_string array>,
|
||||||
|
<total number of entries in the val64_string_array>, /* include {0, NULL} entry */
|
||||||
|
<val64_string_name>);
|
||||||
|
|
||||||
|
For hf[] array FT_(U)INT* fields that need a 'val64stringname_ext' struct, the
|
||||||
|
'strings' field would be set to '&val64stringname_ext'. Furthermore, the 'display'
|
||||||
|
field must be ORed with both 'BASE_EXT_STRING' and 'BASE_VAL64_STRING'
|
||||||
|
(e.g. BASE_DEC|BASE_EXT_STRING|BASE_VAL64_STRING).
|
||||||
|
|
||||||
-- Unit string
|
-- Unit string
|
||||||
Some integer fields, of type FT_UINT* and float fields, of type FT_FLOAT
|
Some integer fields, of type FT_UINT* and float fields, of type FT_FLOAT
|
||||||
or FT_DOUBLE, need units of measurement to help convey the field value.
|
or FT_DOUBLE, need units of measurement to help convey the field value.
|
||||||
|
|
58
epan/proto.c
58
epan/proto.c
|
@ -7651,10 +7651,14 @@ tmp_fld_check_assert(header_field_info *hfinfo)
|
||||||
const value_string *start_values;
|
const value_string *start_values;
|
||||||
const value_string *current;
|
const value_string *current;
|
||||||
|
|
||||||
if (hfinfo->display & BASE_EXT_STRING)
|
if (hfinfo->display & BASE_EXT_STRING) {
|
||||||
start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
|
if (hfinfo->display & BASE_VAL64_STRING)
|
||||||
else
|
start_values = VAL64_STRING_EXT_VS_P(((const val64_string_ext*)hfinfo->strings));
|
||||||
|
else
|
||||||
|
start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
|
||||||
|
} else {
|
||||||
start_values = (const value_string*)hfinfo->strings;
|
start_values = (const value_string*)hfinfo->strings;
|
||||||
|
}
|
||||||
current = start_values;
|
current = start_values;
|
||||||
|
|
||||||
for (n=0; current; n++, current++) {
|
for (n=0; current; n++, current++) {
|
||||||
|
@ -8727,8 +8731,12 @@ hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
|
||||||
if (hfinfo->display & BASE_RANGE_STRING)
|
if (hfinfo->display & BASE_RANGE_STRING)
|
||||||
return try_rval_to_str(value, (const range_string *) hfinfo->strings);
|
return try_rval_to_str(value, (const range_string *) hfinfo->strings);
|
||||||
|
|
||||||
if (hfinfo->display & BASE_EXT_STRING)
|
if (hfinfo->display & BASE_EXT_STRING) {
|
||||||
return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
|
if (hfinfo->display & BASE_VAL64_STRING)
|
||||||
|
return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
|
||||||
|
else
|
||||||
|
return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
|
||||||
|
}
|
||||||
|
|
||||||
if (hfinfo->display & BASE_VAL64_STRING)
|
if (hfinfo->display & BASE_VAL64_STRING)
|
||||||
return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
|
return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
|
||||||
|
@ -10066,7 +10074,11 @@ proto_registrar_dump_values(void)
|
||||||
if (hfinfo->display & BASE_RANGE_STRING) {
|
if (hfinfo->display & BASE_RANGE_STRING) {
|
||||||
range = (const range_string *)hfinfo->strings;
|
range = (const range_string *)hfinfo->strings;
|
||||||
} else if (hfinfo->display & BASE_EXT_STRING) {
|
} else if (hfinfo->display & BASE_EXT_STRING) {
|
||||||
vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
|
if (hfinfo->display & BASE_VAL64_STRING) {
|
||||||
|
vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings);
|
||||||
|
} else {
|
||||||
|
vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
|
||||||
|
}
|
||||||
} else if (hfinfo->display & BASE_VAL64_STRING) {
|
} else if (hfinfo->display & BASE_VAL64_STRING) {
|
||||||
vals64 = (const val64_string *)hfinfo->strings;
|
vals64 = (const val64_string *)hfinfo->strings;
|
||||||
} else if (hfinfo->display & BASE_UNIT_STRING) {
|
} else if (hfinfo->display & BASE_UNIT_STRING) {
|
||||||
|
@ -10083,17 +10095,31 @@ proto_registrar_dump_values(void)
|
||||||
/* Print value strings? */
|
/* Print value strings? */
|
||||||
if (vals) {
|
if (vals) {
|
||||||
if (hfinfo->display & BASE_EXT_STRING) {
|
if (hfinfo->display & BASE_EXT_STRING) {
|
||||||
value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
|
if (hfinfo->display & BASE_VAL64_STRING) {
|
||||||
if (!value_string_ext_validate(vse_p)) {
|
val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
|
||||||
g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
|
if (!val64_string_ext_validate(vse_p)) {
|
||||||
continue;
|
g_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
|
||||||
|
ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
|
||||||
|
hfinfo->abbrev,
|
||||||
|
VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p),
|
||||||
|
VAL64_STRING_EXT_VS_NAME(vse_p),
|
||||||
|
val64_string_ext_match_type_str(vse_p));
|
||||||
|
} else {
|
||||||
|
value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
|
||||||
|
if (!value_string_ext_validate(vse_p)) {
|
||||||
|
g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
|
||||||
|
ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
|
||||||
|
hfinfo->abbrev,
|
||||||
|
VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
|
||||||
|
VALUE_STRING_EXT_VS_NAME(vse_p),
|
||||||
|
value_string_ext_match_type_str(vse_p));
|
||||||
}
|
}
|
||||||
try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
|
|
||||||
ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
|
|
||||||
hfinfo->abbrev,
|
|
||||||
VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
|
|
||||||
VALUE_STRING_EXT_VS_NAME(vse_p),
|
|
||||||
value_string_ext_match_type_str(vse_p));
|
|
||||||
}
|
}
|
||||||
vi = 0;
|
vi = 0;
|
||||||
while (vals[vi].strptr) {
|
while (vals[vi].strptr) {
|
||||||
|
|
|
@ -363,7 +363,7 @@ _try_val_to_str_linear(const guint32 val, value_string_ext *vse)
|
||||||
static const value_string *
|
static const value_string *
|
||||||
_try_val_to_str_index(const guint32 val, value_string_ext *vse)
|
_try_val_to_str_index(const guint32 val, value_string_ext *vse)
|
||||||
{
|
{
|
||||||
guint i;
|
guint32 i;
|
||||||
|
|
||||||
i = val - vse->_vs_first_value;
|
i = val - vse->_vs_first_value;
|
||||||
if (i < vse->_vs_num_entries) {
|
if (i < vse->_vs_num_entries) {
|
||||||
|
@ -434,7 +434,7 @@ _try_val_to_str_ext_init(const guint32 val, value_string_ext *vse)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
guint32 prev_value;
|
guint32 prev_value;
|
||||||
guint first_value;
|
guint32 first_value;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
DISSECTOR_ASSERT((vs_p[vs_num_entries].value == 0) &&
|
DISSECTOR_ASSERT((vs_p[vs_num_entries].value == 0) &&
|
||||||
|
@ -488,6 +488,291 @@ _try_val_to_str_ext_init(const guint32 val, value_string_ext *vse)
|
||||||
return vse->_vs_match2(val, vse);
|
return vse->_vs_match2(val, vse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EXTENDED 64-BIT VALUE STRING */
|
||||||
|
|
||||||
|
/* Extended value strings allow fast(er) val64_string array lookups by
|
||||||
|
* using (if possible) direct access or a binary search of the array.
|
||||||
|
*
|
||||||
|
* If the values in the val64_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 the values in the array are not contiguous (ie: there are "gaps"),
|
||||||
|
* but are in assending order a binary search will be used.
|
||||||
|
*
|
||||||
|
* If direct access or binary search cannot be used, then a linear search
|
||||||
|
* is used and a warning is emitted.
|
||||||
|
*
|
||||||
|
* Note that the val64_string array used with VAL64_STRING_EXT_INIT
|
||||||
|
* *must* be terminated with {0, NULL}).
|
||||||
|
*
|
||||||
|
* Extended value strings are defined at compile time as follows:
|
||||||
|
* static const val64_string vs[] = { {value1, "string1"},
|
||||||
|
* {value2, "string2"},
|
||||||
|
* ...,
|
||||||
|
* {0, NULL}};
|
||||||
|
* static val64_string_ext vse = VAL64_STRING_EXT_INIT(vs);
|
||||||
|
*
|
||||||
|
* Extended value strings can be created at runtime by calling
|
||||||
|
* val64_string_ext_new(<ptr to val64_string array>,
|
||||||
|
* <total number of entries in the val64_string_array>,
|
||||||
|
* <val64_string_name>);
|
||||||
|
* Note: The <total number of entries in the val64_string_array> should include
|
||||||
|
* the {0, NULL} entry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Create a val64_string_ext given a ptr to a val64_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 an epan-scoped'd and initialized val64_string_ext
|
||||||
|
* struct. */
|
||||||
|
val64_string_ext *
|
||||||
|
val64_string_ext_new(const val64_string *vs, guint vs_tot_num_entries,
|
||||||
|
const gchar *vs_name)
|
||||||
|
{
|
||||||
|
val64_string_ext *vse;
|
||||||
|
|
||||||
|
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 = wmem_new(wmem_epan_scope(), val64_string_ext);
|
||||||
|
vse->_vs_p = vs;
|
||||||
|
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 = _try_val64_to_str_ext_init;
|
||||||
|
vse->_vs_name = vs_name;
|
||||||
|
|
||||||
|
return vse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
val64_string_ext_free(val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
wmem_free(wmem_epan_scope(), vse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like try_val_to_str for extended value strings */
|
||||||
|
const gchar *
|
||||||
|
try_val64_to_str_ext(const guint64 val, val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
if (vse) {
|
||||||
|
const val64_string *vs = vse->_vs_match2(val, vse);
|
||||||
|
|
||||||
|
if (vs) {
|
||||||
|
return vs->strptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like try_val_to_str_idx for extended value strings */
|
||||||
|
const gchar *
|
||||||
|
try_val64_to_str_idx_ext(const guint64 val, val64_string_ext *vse, gint *idx)
|
||||||
|
{
|
||||||
|
if (vse) {
|
||||||
|
const val64_string *vs = vse->_vs_match2(val, vse);
|
||||||
|
if (vs) {
|
||||||
|
*idx = (gint) (vs - vse->_vs_p);
|
||||||
|
return vs->strptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*idx = -1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like val_to_str for extended value strings */
|
||||||
|
const gchar *
|
||||||
|
val64_to_str_ext(const guint64 val, val64_string_ext *vse, const char *fmt)
|
||||||
|
{
|
||||||
|
const gchar *ret;
|
||||||
|
|
||||||
|
DISSECTOR_ASSERT(fmt != NULL);
|
||||||
|
|
||||||
|
ret = try_val64_to_str_ext(val, vse);
|
||||||
|
if (ret != NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return wmem_strdup_printf(wmem_packet_scope(), fmt, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
val64_to_str_ext_wmem(wmem_allocator_t *scope, const guint64 val, val64_string_ext *vse, const char *fmt)
|
||||||
|
{
|
||||||
|
const gchar *ret;
|
||||||
|
|
||||||
|
DISSECTOR_ASSERT(fmt != NULL);
|
||||||
|
|
||||||
|
ret = try_val64_to_str_ext(val, vse);
|
||||||
|
if (ret != NULL)
|
||||||
|
return wmem_strdup(scope, ret);
|
||||||
|
|
||||||
|
return wmem_strdup_printf(scope, fmt, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like val_to_str_const for extended value strings */
|
||||||
|
const gchar *
|
||||||
|
val64_to_str_ext_const(const guint64 val, val64_string_ext *vse,
|
||||||
|
const char *unknown_str)
|
||||||
|
{
|
||||||
|
const gchar *ret;
|
||||||
|
|
||||||
|
DISSECTOR_ASSERT(unknown_str != NULL);
|
||||||
|
|
||||||
|
ret = try_val64_to_str_ext(val, vse);
|
||||||
|
if (ret != NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return unknown_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback linear matching algorithm for extended value strings */
|
||||||
|
static const val64_string *
|
||||||
|
_try_val64_to_str_linear(const guint64 val, val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
const val64_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 val64_string *
|
||||||
|
_try_val64_to_str_index(const guint64 val, val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
guint64 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 val64_string *
|
||||||
|
_try_val64_to_str_bsearch(const guint64 val, val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
guint low, i, max;
|
||||||
|
guint64 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes an extended value string. Behaves like a match function to
|
||||||
|
* permit lazy initialization of extended value strings.
|
||||||
|
* - Goes through the val64_string array to determine the fastest possible
|
||||||
|
* access method.
|
||||||
|
* - Verifies that the val64_string contains no NULL string pointers.
|
||||||
|
* - Verifies that the val64_string is terminated by {0, NULL}
|
||||||
|
*/
|
||||||
|
const val64_string *
|
||||||
|
_try_val64_to_str_ext_init(const guint64 val, val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
const val64_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 val64_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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
guint64 prev_value;
|
||||||
|
guint64 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:\n"
|
||||||
|
" entry %u, value %" G_GINT64_MODIFIER "u [%#" G_GINT64_MODIFIER "x] < previous entry, value %" G_GINT64_MODIFIER "u [%#" G_GINT64_MODIFIER "x]",
|
||||||
|
vse->_vs_name, i, vs_p[i].value, vs_p[i].value, prev_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:\n"
|
||||||
|
" entry %u, value %" G_GINT64_MODIFIER "u [%#" G_GINT64_MODIFIER "x] < first entry, value %" G_GINT64_MODIFIER "u [%#" G_GINT64_MODIFIER "x]",
|
||||||
|
vse->_vs_name, i, vs_p[i].value, vs_p[i].value, first_value, first_value);
|
||||||
|
type = VS_SEARCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_value = vs_p[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case VS_SEARCH:
|
||||||
|
vse->_vs_match2 = _try_val64_to_str_linear;
|
||||||
|
break;
|
||||||
|
case VS_BIN_TREE:
|
||||||
|
vse->_vs_match2 = _try_val64_to_str_bsearch;
|
||||||
|
break;
|
||||||
|
case VS_INDEX:
|
||||||
|
vse->_vs_match2 = _try_val64_to_str_index;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vse->_vs_match2(val, vse);
|
||||||
|
}
|
||||||
|
|
||||||
/* STRING TO STRING MATCHING */
|
/* STRING TO STRING MATCHING */
|
||||||
|
|
||||||
/* string_string is like value_string except the values being matched are
|
/* string_string is like value_string except the values being matched are
|
||||||
|
@ -739,6 +1024,35 @@ value_string_ext_match_type_str(const value_string_ext *vse)
|
||||||
return "[Invalid]";
|
return "[Invalid]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
val64_string_ext_validate(const val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
if (vse == NULL)
|
||||||
|
return FALSE;
|
||||||
|
#ifndef _WIN32 /* doesn't work on Windows for refs from another DLL ?? */
|
||||||
|
if ((vse->_vs_match2 != _try_val64_to_str_ext_init) &&
|
||||||
|
(vse->_vs_match2 != _try_val64_to_str_linear) &&
|
||||||
|
(vse->_vs_match2 != _try_val64_to_str_bsearch) &&
|
||||||
|
(vse->_vs_match2 != _try_val64_to_str_index))
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
val64_string_ext_match_type_str(const val64_string_ext *vse)
|
||||||
|
{
|
||||||
|
if (vse->_vs_match2 == _try_val64_to_str_ext_init)
|
||||||
|
return "[Not Initialized]";
|
||||||
|
if (vse->_vs_match2 == _try_val64_to_str_linear)
|
||||||
|
return "[Linear Search]";
|
||||||
|
if (vse->_vs_match2 == _try_val64_to_str_bsearch)
|
||||||
|
return "[Binary Search]";
|
||||||
|
if (vse->_vs_match2 == _try_val64_to_str_index)
|
||||||
|
return "[Direct (indexed) Access]";
|
||||||
|
return "[Invalid]";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||||
*
|
*
|
||||||
|
|
|
@ -209,6 +209,59 @@ WS_DLL_PUBLIC
|
||||||
const gchar *
|
const gchar *
|
||||||
try_val_to_str_idx_ext(const guint32 val, value_string_ext *vse, gint *idx);
|
try_val_to_str_idx_ext(const guint32 val, value_string_ext *vse, gint *idx);
|
||||||
|
|
||||||
|
/* EXTENDED 64-BIT VALUE TO STRING MATCHING */
|
||||||
|
|
||||||
|
typedef struct _val64_string_ext val64_string_ext;
|
||||||
|
typedef const val64_string *(*_val64_string_match2_t)(const guint64, val64_string_ext*);
|
||||||
|
|
||||||
|
struct _val64_string_ext {
|
||||||
|
_val64_string_match2_t _vs_match2;
|
||||||
|
guint64 _vs_first_value; /* first value of the val64_string array */
|
||||||
|
guint _vs_num_entries; /* number of entries in the val64_string array */
|
||||||
|
/* (excluding final {0, NULL}) */
|
||||||
|
const val64_string *_vs_p; /* the value string array address */
|
||||||
|
const gchar *_vs_name; /* vse "Name" (for error messages) */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VAL64_STRING_EXT_VS_P(x) (x)->_vs_p
|
||||||
|
#define VAL64_STRING_EXT_VS_NUM_ENTRIES(x) (x)->_vs_num_entries
|
||||||
|
#define VAL64_STRING_EXT_VS_NAME(x) (x)->_vs_name
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
const val64_string *
|
||||||
|
_try_val64_to_str_ext_init(const guint64 val, val64_string_ext *vse);
|
||||||
|
#define VAL64_STRING_EXT_INIT(x) { _try_val64_to_str_ext_init, 0, G_N_ELEMENTS(x)-1, x, #x }
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
val64_string_ext *
|
||||||
|
val64_string_ext_new(const val64_string *vs, guint vs_tot_num_entries, const gchar *vs_name);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
void
|
||||||
|
val64_string_ext_free(val64_string_ext *vse);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
const gchar *
|
||||||
|
val64_to_str_ext(const guint64 val, val64_string_ext *vse, const char *fmt)
|
||||||
|
G_GNUC_PRINTF(3, 0);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
gchar *
|
||||||
|
val64_to_str_ext_wmem(wmem_allocator_t *scope, const guint64 val, val64_string_ext *vse, const char *fmt)
|
||||||
|
G_GNUC_PRINTF(4, 0);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
const gchar *
|
||||||
|
val64_to_str_ext_const(const guint64 val, val64_string_ext *vs, const char *unknown_str);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
const gchar *
|
||||||
|
try_val64_to_str_ext(const guint64 val, val64_string_ext *vse);
|
||||||
|
|
||||||
|
WS_DLL_PUBLIC
|
||||||
|
const gchar *
|
||||||
|
try_val64_to_str_idx_ext(const guint64 val, val64_string_ext *vse, gint *idx);
|
||||||
|
|
||||||
/* STRING TO STRING MATCHING */
|
/* STRING TO STRING MATCHING */
|
||||||
|
|
||||||
typedef struct _string_string {
|
typedef struct _string_string {
|
||||||
|
@ -298,6 +351,14 @@ WS_DLL_LOCAL
|
||||||
const gchar *
|
const gchar *
|
||||||
value_string_ext_match_type_str(const value_string_ext *vse);
|
value_string_ext_match_type_str(const value_string_ext *vse);
|
||||||
|
|
||||||
|
WS_DLL_LOCAL
|
||||||
|
gboolean
|
||||||
|
val64_string_ext_validate(const val64_string_ext *vse);
|
||||||
|
|
||||||
|
WS_DLL_LOCAL
|
||||||
|
const gchar *
|
||||||
|
val64_string_ext_match_type_str(const val64_string_ext *vse);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
Loading…
Reference in New Issue