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  }