aboutsummaryrefslogtreecommitdiffstats
path: root/epan/value_string.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2010-04-27 12:38:49 +0000
committerAnders Broman <anders.broman@ericsson.com>2010-04-27 12:38:49 +0000
commitab825ec9d9d827ed5333778bd26f7ca20b839975 (patch)
treee49249d0cb639081456995b404e34b441f01d449 /epan/value_string.c
parenta34b791645c410f5b0e6d3c0324c8cef79e4e7e9 (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
Diffstat (limited to 'epan/value_string.c')
-rw-r--r--epan/value_string.c104
1 files changed, 78 insertions, 26 deletions
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.