bytereader.go raw

   1  // Copyright 2019+ Klaus Post. All rights reserved.
   2  // License information can be found in the LICENSE file.
   3  // Based on work by Yann Collet, released under BSD License.
   4  
   5  package zstd
   6  
   7  // byteReader provides a byte reader that reads
   8  // little endian values from a byte stream.
   9  // The input stream is manually advanced.
  10  // The reader performs no bounds checks.
  11  type byteReader struct {
  12  	b   []byte
  13  	off int
  14  }
  15  
  16  // advance the stream b n bytes.
  17  func (b *byteReader) advance(n uint) {
  18  	b.off += int(n)
  19  }
  20  
  21  // overread returns whether we have advanced too far.
  22  func (b *byteReader) overread() bool {
  23  	return b.off > len(b.b)
  24  }
  25  
  26  // Int32 returns a little endian int32 starting at current offset.
  27  func (b byteReader) Int32() int32 {
  28  	b2 := b.b[b.off:]
  29  	b2 = b2[:4]
  30  	v3 := int32(b2[3])
  31  	v2 := int32(b2[2])
  32  	v1 := int32(b2[1])
  33  	v0 := int32(b2[0])
  34  	return v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)
  35  }
  36  
  37  // Uint8 returns the next byte
  38  func (b *byteReader) Uint8() uint8 {
  39  	v := b.b[b.off]
  40  	return v
  41  }
  42  
  43  // Uint32 returns a little endian uint32 starting at current offset.
  44  func (b byteReader) Uint32() uint32 {
  45  	if r := b.remain(); r < 4 {
  46  		// Very rare
  47  		v := uint32(0)
  48  		for i := 1; i <= r; i++ {
  49  			v = (v << 8) | uint32(b.b[len(b.b)-i])
  50  		}
  51  		return v
  52  	}
  53  	b2 := b.b[b.off:]
  54  	b2 = b2[:4]
  55  	v3 := uint32(b2[3])
  56  	v2 := uint32(b2[2])
  57  	v1 := uint32(b2[1])
  58  	v0 := uint32(b2[0])
  59  	return v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)
  60  }
  61  
  62  // Uint32NC returns a little endian uint32 starting at current offset.
  63  // The caller must be sure if there are at least 4 bytes left.
  64  func (b byteReader) Uint32NC() uint32 {
  65  	b2 := b.b[b.off:]
  66  	b2 = b2[:4]
  67  	v3 := uint32(b2[3])
  68  	v2 := uint32(b2[2])
  69  	v1 := uint32(b2[1])
  70  	v0 := uint32(b2[0])
  71  	return v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)
  72  }
  73  
  74  // unread returns the unread portion of the input.
  75  func (b byteReader) unread() []byte {
  76  	return b.b[b.off:]
  77  }
  78  
  79  // remain will return the number of bytes remaining.
  80  func (b byteReader) remain() int {
  81  	return len(b.b) - b.off
  82  }
  83