diff options
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r-- | epan/tvbuff.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c index edd0f049a4..98e4e71748 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -3649,20 +3649,45 @@ tvb_get_ds_tvb(tvbuff_t *tvb) } guint -tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value) +tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const guint encoding) { - guint i; - guint64 b; /* current byte */ *value = 0; - for (i = 0; ((i < FT_VARINT_MAX_LEN) && (i < maxlen)); ++i) { - b = tvb_get_guint8(tvb, offset++); - *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */ + if (encoding & ENC_VARINT_PROTOBUF) { + guint i; + guint64 b; /* current byte */ - if (b < 0x80) { - /* end successfully becauseof last byte's msb(most significant bit) is zero */ - return i + 1; + for (i = 0; ((i < FT_VARINT_MAX_LEN) && (i < maxlen)); ++i) { + b = tvb_get_guint8(tvb, offset++); + *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */ + + if (b < 0x80) { + /* end successfully becauseof last byte's msb(most significant bit) is zero */ + return i + 1; + } } + } else if (encoding & ENC_VARINT_QUIC) { + + /* calculate variable length */ + *value = tvb_get_guint8(tvb, offset); + switch((*value) >> 6) { + case 0: /* 0b00 => 1 byte length (6 bits Usable) */ + (*value) &= 0x3F; + return 1; + case 1: /* 0b01 => 2 bytes length (14 bits Usable) */ + *value = tvb_get_ntohs(tvb, offset) & 0x3FFF; + return 2; + case 2: /* 0b10 => 4 bytes length (30 bits Usable) */ + *value = tvb_get_ntohl(tvb, offset) & 0x3FFFFFFF; + return 4; + case 3: /* 0b11 => 8 bytes length (62 bits Usable) */ + *value = tvb_get_ntoh64(tvb, offset) & G_GUINT64_CONSTANT(0x3FFFFFFFFFFFFFFF); + return 8; + default: /* No Possible */ + g_assert_not_reached(); + break; + } + } return 0; /* 10 bytes scanned, but no bytes' msb is zero */ |