In the patch I sent out a few days ago showing the current development
on the new proto_tree stuff, my header_field_info struct is this:
/* information describing a header field */
typedef struct header_field_info {
char *name;
char *abbrev;
enum ftenum type;
int display;
void *strings;
struct bitfield_info bfinfo;
char *blurb;
int id;
int parent;
} header_field_info;
It contains an entire bitfield_info struct, which looks like this.
typedef struct bitfield_info {
gboolean is_bitfield;
guint32 bitmask;
gint8 shift;
} bitfield_info;
I made it that way so that we could initialize structs easily. When a
field _is_ a bitfield, we put TRUE in the bitfield_info struct and
initialize the rest of the members. When the field is not a bitfield,
we use FALSE and let C initialize the rest of the members of the
bitfield_info to 0.
{ &hf_sna_rh_pi,
{ "Pacing Indicator", "sna.rh.pi", FT_BOOLEAN, 8, NULL, { TRUE, 0x01, 0 },
"" }},
{ &hf_sna_ru,
{ "Request/Response Unit", "sna.ru", FT_NONE, BASE_NONE, NULL, { FALSE },
""}},
Today I realized that having both 'bitmask' and 'shift' in the
bitfield_info is redundant. At registration time, 'shift' can be deduced
from 'bitmask' by finding the first non-zero bit. I should be able
to tell the proto_tree registration routine that the bitmask for
"sna.rh.pi" is 0x01, and it should figure out that since I'm looking at
the first bit, I don't have to shift the bits over the the right at all.
If the bitmask were 0x10, then it can easily be deduce that the
shift value should be 4, since the first set bit is the 5th bit (the
first bit in the high nibble), and it would take 4 shifts to move that
bit to the first position in the byte. The computer can figure it out
for us.
Can anyone think of any cases where this automatic deduction would
not work or be appropriate? If I can use it, then I can get rid of
the 'shift' field as well as the 'is_bitfield' flag in bitfield_info. Then
I can get rid of the bitfield_info struct entirely, and just put
the 'bitmask' into header_field_info. If bitmask is 0, then I can
assume that the field is _not_ a bitfield (otherwise we'd get no value
if we actually applied that bitfield). If bitmask is _not_ 0, then the field
is a bitfield. Then the two examples above would be:
{ &hf_sna_rh_pi,
{ "Pacing Indicator", "sna.rh.pi", FT_BOOLEAN, 8, NULL, /*bitmask*/ 0x01,
"" }},
{ &hf_sna_ru,
{ "Request/Response Unit", "sna.ru", FT_NONE, BASE_NONE, NULL, /*BM*/ 0,
""}},
--gilbert