github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/p2p/encoder/varint.go (about) 1 package encoder 2 3 import ( 4 "io" 5 6 "github.com/gogo/protobuf/proto" 7 "github.com/pkg/errors" 8 ) 9 10 const maxVarintLength = 10 11 12 var errExcessMaxLength = errors.Errorf("provided header exceeds the max varint length of %d bytes", maxVarintLength) 13 14 // readVarint at the beginning of a byte slice. This varint may be used to indicate 15 // the length of the remaining bytes in the reader. 16 func readVarint(r io.Reader) (uint64, error) { 17 b := make([]byte, 0, maxVarintLength) 18 for i := 0; i < maxVarintLength; i++ { 19 b1 := make([]byte, 1) 20 n, err := r.Read(b1) 21 if err != nil { 22 return 0, err 23 } 24 if n != 1 { 25 return 0, errors.New("did not read a byte from stream") 26 } 27 b = append(b, b1[0]) 28 29 // If most significant bit is not set, we have reached the end of the Varint. 30 if b1[0]&0x80 == 0 { 31 break 32 } 33 34 // If the varint is larger than 10 bytes, it is invalid as it would 35 // exceed the size of MaxUint64. 36 if i+1 >= maxVarintLength { 37 return 0, errExcessMaxLength 38 } 39 } 40 41 vi, n := proto.DecodeVarint(b) 42 if n != len(b) { 43 return 0, errors.New("varint did not decode entire byte slice") 44 } 45 return vi, nil 46 }