| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- package qpack
- // copied from the Go standard library HPACK implementation
- import "errors"
- var errVarintOverflow = errors.New("varint integer overflow")
- // appendVarInt appends i, as encoded in variable integer form using n
- // bit prefix, to dst and returns the extended buffer.
- //
- // See
- // http://http2.github.io/http2-spec/compression.html#integer.representation
- func appendVarInt(dst []byte, n byte, i uint64) []byte {
- k := uint64((1 << n) - 1)
- if i < k {
- return append(dst, byte(i))
- }
- dst = append(dst, byte(k))
- i -= k
- for ; i >= 128; i >>= 7 {
- dst = append(dst, byte(0x80|(i&0x7f)))
- }
- return append(dst, byte(i))
- }
- // readVarInt reads an unsigned variable length integer off the
- // beginning of p. n is the parameter as described in
- // http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
- //
- // n must always be between 1 and 8.
- //
- // The returned remain buffer is either a smaller suffix of p, or err != nil.
- // The error is errNeedMore if p doesn't contain a complete integer.
- func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
- if n < 1 || n > 8 {
- panic("bad n")
- }
- if len(p) == 0 {
- return 0, p, errNeedMore
- }
- i = uint64(p[0])
- if n < 8 {
- i &= (1 << uint64(n)) - 1
- }
- if i < (1<<uint64(n))-1 {
- return i, p[1:], nil
- }
- origP := p
- p = p[1:]
- var m uint64
- for len(p) > 0 {
- b := p[0]
- p = p[1:]
- i += uint64(b&127) << m
- if b&128 == 0 {
- return i, p, nil
- }
- m += 7
- if m >= 63 { // TODO: proper overflow check. making this up.
- return 0, origP, errVarintOverflow
- }
- }
- return 0, origP, errNeedMore
- }
|