diff options
author | Anders Broman <anders.broman@ericsson.com> | 2007-04-28 12:13:25 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2007-04-28 12:13:25 +0000 |
commit | 43bb2aea51286c1b9c2d07e87f9a70374a849323 (patch) | |
tree | 519aeae421e1cf955875c5c2345952c41ec9eee9 /epan/tvbuff.c | |
parent | 3094ff6c619ec5b0b498d9672ebc86c88258c0f9 (diff) | |
download | wireshark-43bb2aea51286c1b9c2d07e87f9a70374a849323.tar.gz |
Add:
proto_tree_add_bits_ret_val()
tvb_get_bits()
And modify
proto_tree_add_bits() not to return a value.
little endian is not yet implemented.
svn path=/trunk/; revision=21607
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r-- | epan/tvbuff.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 4ebc655062..2497ac1752 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -1446,6 +1446,121 @@ tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian) } } +static const guint8 bit_mask[] = { + 0xff, + 0x7f, + 0x3f, + 0x1f, + 0x0f, + 0x07, + 0x03, + 0x01 +}; + +guint64 +tvb_get_bits(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian) +{ + + gint offset; + guint64 value = 0; + guint64 tempval = 0; + guint8 tot_no_bits; + guint8 num_octs; + guint8 shift; + + if (no_of_bits>64) + DISSECTOR_ASSERT_NOT_REACHED(); + if(little_endian){ + DISSECTOR_ASSERT_NOT_REACHED(); + /* This part is not implemented yet */ + } + + /* Byte align offset */ + offset = bit_offset>>3; + + /* Find out which mask to use for the most significant octet + * by convering bit_offset into the offset into the first + * fetched octet. + */ + bit_offset = bit_offset & 0x7; + /* calculate number of octets to read */ + tot_no_bits = bit_offset + no_of_bits; + num_octs = tot_no_bits>>3; + /* Calculate shift value for most significant bits in the first octet */ + shift = 8 * (num_octs-1); + + + if ((tot_no_bits&0x7)!=0) + num_octs++; + + tempval = tvb_get_guint8(tvb,offset)&bit_mask[bit_offset]; + tempval = tempval << shift; + + switch(num_octs){ + case 1: + /* Total 8 bits */ + value = tempval >> (8-no_of_bits); + break; + case 2: + /* Total 8 + 8 = 16*/ + value = tempval | tvb_get_guint8(tvb,offset+1); + value = value >> (16 - tot_no_bits); + break; + case 3: + /* Total 8 + 16 = 24*/ + value = tempval | tvb_get_ntohs(tvb,offset+1); + value = value >> (24 - tot_no_bits); + break; + case 4: + /* Total 8 + 24 = 32*/ + value = tempval | tvb_get_ntoh24(tvb,offset+1); + value = value >> (32 - tot_no_bits); + break; + case 5: + /* total 8 + 32 = 40*/ + value = tempval | (tvb_get_ntohl(tvb,offset+1)); + value = value >> (40 - tot_no_bits); + break; + case 6: + /* total 8 + 32 + 8 = 48*/ + tempval = tvb_get_ntohl(tvb,offset+1); + tempval = tempval <<8; + value = value | tempval; + value = value | tvb_get_guint8(tvb,offset+5); + value = value >> (48 - tot_no_bits); + break; + case 7: + /* total 8 + 32 + 16 = 56*/ + tempval = tvb_get_ntohl(tvb,offset+1); + tempval = tempval <<16; + value = value | tempval; + value = value >> (56 - tot_no_bits); + break; + case 8: + /* total 8 + 32 + 24 = 64*/ + tempval = tvb_get_ntohl(tvb,offset+1); + tempval = tempval <<24; + value = value | tempval; + value = value | tvb_get_ntoh24(tvb,offset+5); + value = value >> (64 - tot_no_bits); + break; + case 9: + /* total 8 +64 = 72 + * If bit_offset = 7 and no_of_bits=64 nine bytes is needed. + */ + value = tempval | tvb_get_ntoh64(tvb,offset+1); + value = value >> (72 - tot_no_bits); + break; + default: + DISSECTOR_ASSERT_NOT_REACHED(); + return NULL; + break; + } + + return value; + +} + /* Find first occurence of needle in tvbuff, starting at offset. Searches * at most maxlength number of bytes; if maxlength is -1, searches to * end of tvbuff. |