diff options
author | Anders Broman <anders.broman@ericsson.com> | 2010-04-27 12:38:49 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2010-04-27 12:38:49 +0000 |
commit | ab825ec9d9d827ed5333778bd26f7ca20b839975 (patch) | |
tree | e49249d0cb639081456995b404e34b441f01d449 | |
parent | a34b791645c410f5b0e6d3c0324c8cef79e4e7e9 (diff) |
From Jakub Zawadzki:
- use function pointers instead of switch.
- initalize ->match_type during first use of match_str() func.
svn path=/trunk/; revision=32576
-rw-r--r-- | epan/proto.c | 27 | ||||
-rw-r--r-- | epan/proto.h | 4 | ||||
-rw-r--r-- | epan/value_string.c | 104 | ||||
-rw-r--r-- | epan/value_string.h | 19 |
4 files changed, 84 insertions, 70 deletions
diff --git a/epan/proto.c b/epan/proto.c index 2d6761a0b8..6d22b50150 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -4393,39 +4393,12 @@ static void tmp_fld_check_assert(header_field_info *hfinfo) { } } -static void -proto_reinit_value_string(value_string_ext *vse) -{ - const value_string *vals = vse->vals; - int type = VS_INDEX; - guint32 prev = 0; - guint i; - - for (i = 0; i < vse->length; i++) { - if (type == VS_INDEX && vals[i].value != i) - type = VS_BIN_TREE; - - if (type == VS_BIN_TREE && prev > vals[i].value) { - type = VS_SEARCH; - break; - } - - prev = vals[i].value; - } - - vse->match_type = type; - printf("%p: %d\n", vse, type); -} - static int proto_register_field_init(header_field_info *hfinfo, const int parent) { tmp_fld_check_assert(hfinfo); - if (hfinfo->strings && (hfinfo->display & BASE_EXT_STRING) && IS_INT_TYPE(hfinfo->type)) - proto_reinit_value_string((value_string_ext *) hfinfo->strings); - /* if this is a bitfield, compute bitshift */ if (hfinfo->bitmask) { hfinfo->bitshift = wrs_count_bitshift(hfinfo->bitmask); diff --git a/epan/proto.h b/epan/proto.h index 97b934dcba..49394ebc08 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -159,10 +159,6 @@ typedef enum { BASE_CUSTOM /**< call custom routine (in ->strings) to format */ } base_display_e; -#define IS_INT_TYPE(type) \ - ((type) == FT_UINT8 || (type) == FT_UINT16 || (type) == FT_UINT24 || (type) == FT_UINT32 || (type) == FT_UINT64 || \ - (type) == FT_INT8 || (type) == FT_INT16 || (type) == FT_INT24 || (type) == FT_INT32 || (type) == FT_INT64) - /* Following constants have to be ORed with a base_display_e when dissector * want to use specials MACROs (for the moment, only RVALS) for a * header_field_info */ diff --git a/epan/value_string.c b/epan/value_string.c index 44b06478c5..a2b45f9cc2 100644 --- a/epan/value_string.c +++ b/epan/value_string.c @@ -120,39 +120,91 @@ match_strval(const guint32 val, const value_string *vs) { return match_strval_idx(val, vs, &ignore_me); } -const gchar* -match_strval_ext(const guint32 val, const value_string_ext *vs) { +static const gchar * +_match_strval_linear(const guint32 val, const value_string_ext *vs) +{ + return match_strval(val, vs->vals); +} + +static const gchar * +_match_strval_index(const guint32 val, const value_string_ext *vs) +{ + return (val < vs->length) ? vs->vals[val].strptr : NULL; +} + +static const gchar * +_match_strval_bsearch(const guint32 val, const value_string_ext *vs) +{ guint low, idx, max; guint32 item; - if(vs) { - switch(vs->match_type){ - case VS_DEFAULT: - /* XXX: reinit? */ - case VS_SEARCH: - return match_strval(val, vs->vals); - case VS_INDEX: - return (val < vs->length) ? vs->vals[val].strptr : NULL; - case VS_BIN_TREE: - for (low = 0, max = vs->length; low < max; ) { - idx = (low + max) / 2; - item = vs->vals[idx].value; - - if (val < item) - max = idx; - else if (val > item) - low = idx + 1; - else - return vs->vals[idx].strptr; - } - break; - default: - g_assert_not_reached(); + + for (low = 0, max = vs->length; low < max; ) { + idx = (low + max) / 2; + item = vs->vals[idx].value; + + if (val < item) + max = idx; + else if (val > item) + low = idx + 1; + else + return vs->vals[idx].strptr; + } + return NULL; +} + +const gchar * +match_strval_ext_init(const guint32 val, value_string_ext *vse) +{ + const value_string *vals = vse->vals; + +/* The way matching of value is done in a value_string: + * 0 default, value will be set in proto_register_field_init() + * 1 Sequential search (as in a normal value string) + * 2 The value used as an index(the value string MUST have all values 0-max defined) + * 3 Binary search, the valuse MUST be in numerical order. + */ + enum { VS_SEARCH = 0, VS_INDEX, VS_BIN_TREE } type = VS_INDEX; + + guint32 prev = 0; + guint i; + + for (i = 0; i < vse->length; i++) { + if (type == VS_INDEX && vals[i].value != i) + type = VS_BIN_TREE; + + if (type == VS_BIN_TREE && prev > vals[i].value) { + type = VS_SEARCH; break; } + + prev = vals[i].value; } - return NULL; + + switch (type) { + case VS_SEARCH: + vse->match = _match_strval_linear; + break; + case VS_INDEX: + vse->match = _match_strval_index; + break; + case VS_BIN_TREE: + vse->match = _match_strval_bsearch; + break; + default: + g_assert_not_reached(); + break; + } + + printf("%p: %d\n", vse, type); + return vse->match(val, vse); } +const gchar* +match_strval_ext(const guint32 val, const value_string_ext *vs) { + if (vs) + return vs->match(val, vs); + return NULL; +} /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr on a match. diff --git a/epan/value_string.h b/epan/value_string.h index 677ebb6c37..aa73ba058f 100644 --- a/epan/value_string.h +++ b/epan/value_string.h @@ -34,24 +34,17 @@ typedef struct _value_string { const gchar *strptr; } value_string; -/* The way matching of value is done in a value_string: - * 0 default, value will be set in proto_register_field_init() - * 1 Sequential search (as in a normal value string) - * 2 The value used as an index(the value string MUST have all values 0-max defined) - * 3 Binary search, the valuse MUST be in numerical order. - */ -#define VS_DEFAULT 0 -#define VS_SEARCH 1 -#define VS_INDEX 2 -#define VS_BIN_TREE 3 +struct _value_string_ext; +typedef const char *(*value_string_match_t)(const guint32, const struct _value_string_ext *); -typedef struct { - guint match_type; /* One of the values abowe */ +typedef struct _value_string_ext { + value_string_match_t match; guint length; /* length of the array */ const value_string *vals; /* the value string */ } value_string_ext; -#define VALUE_STRING_EXT_INIT(x) { VS_DEFAULT, array_length(x)-1, x } +const gchar *match_strval_ext_init(const guint32 val, value_string_ext *vse); +#define VALUE_STRING_EXT_INIT(x) { (value_string_match_t) match_strval_ext_init, array_length(x)-1, x } /* Struct for the str_to_str, match_strstr_idx, and match_strstr functions */ |