Add generic tvb_get_bits_buf() which accepts any no_of_bits.
svn path=/trunk/; revision=37217
This commit is contained in:
parent
1372515b02
commit
e21e71e46e
|
@ -387,6 +387,7 @@ ep_strdup_printf
|
|||
ep_strdup_vprintf
|
||||
ep_strndup
|
||||
ep_strsplit
|
||||
ep_tvb_get_bits
|
||||
ep_tvb_memdup
|
||||
epan_base64_decode
|
||||
epan_cleanup
|
||||
|
@ -1069,6 +1070,7 @@ tvb_find_line_end_unquoted
|
|||
tvb_format_text
|
||||
tvb_format_text_wsp
|
||||
tvb_free
|
||||
tvb_get_bits_buf
|
||||
tvb_get_bits8
|
||||
tvb_get_bits16
|
||||
tvb_get_bits32
|
||||
|
|
|
@ -1656,6 +1656,59 @@ tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits)
|
|||
return (guint8)value;
|
||||
}
|
||||
|
||||
void
|
||||
tvb_get_bits_buf(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, guint8 *buf)
|
||||
{
|
||||
/* Byte align offset */
|
||||
gint offset = bit_offset >> 3;
|
||||
bit_offset = bit_offset & 0x7;
|
||||
|
||||
if (G_LIKELY(bit_offset != 0)) {
|
||||
/* XXX, this can be optimized */
|
||||
while (no_of_bits >= 8) {
|
||||
guint16 value = (tvb_get_ntohs(tvb, offset) & bit_mask16[bit_offset]) >> (8 - bit_offset);
|
||||
|
||||
*buf++ = (guint8) value;
|
||||
offset++;
|
||||
no_of_bits -= 8;
|
||||
}
|
||||
|
||||
/* something left? */
|
||||
if (no_of_bits > 0)
|
||||
*buf = tvb_get_bits8(tvb, offset * 8 + bit_offset, no_of_bits);
|
||||
|
||||
} else {
|
||||
/* fast code path for bit_offset == 0 */
|
||||
while (no_of_bits >= 8) {
|
||||
*buf++ = tvb_get_guint8(tvb, offset);
|
||||
offset++;
|
||||
no_of_bits -= 8;
|
||||
}
|
||||
|
||||
/* something left? */
|
||||
if (no_of_bits > 0)
|
||||
*buf = tvb_get_guint8(tvb, offset) >> (8-no_of_bits);
|
||||
}
|
||||
}
|
||||
|
||||
guint8 *
|
||||
ep_tvb_get_bits(tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
|
||||
{
|
||||
gint no_of_bytes;
|
||||
guint8 *buf;
|
||||
|
||||
/* XXX, no_of_bits == -1 -> to end of tvb? */
|
||||
|
||||
if (no_of_bits < 0 || bit_offset < 0) {
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
no_of_bytes = (no_of_bits >> 3) + ((no_of_bits & 0x7) != 0); /* ceil(no_of_bits / 8.0) */
|
||||
buf = ep_alloc(no_of_bytes);
|
||||
tvb_get_bits_buf(tvb, bit_offset, no_of_bits, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Get 9 - 16 bits */
|
||||
/* Bit offset mask for number of bits = 16 - 32 */
|
||||
static const guint32 bit_mask32[] = {
|
||||
|
|
|
@ -363,6 +363,9 @@ extern guint64 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, const gint no_of_b
|
|||
*/
|
||||
extern guint32 tvb_get_bits(tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian);
|
||||
|
||||
void tvb_get_bits_buf(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, guint8 *buf);
|
||||
guint8 *ep_tvb_get_bits(tvbuff_t *tvb, gint bit_offset, gint no_of_bits);
|
||||
|
||||
/** Returns target for convenience. Does not suffer from possible
|
||||
* expense of tvb_get_ptr(), since this routine is smart enough
|
||||
* to copy data in chunks if the request range actually exists in
|
||||
|
|
Loading…
Reference in New Issue