hunk.code_window:       - "10025:10025"
         - "10080:10080"
         - "10110:10110"
       extends:
           file: build/docker-compose.common.yml
           service: inbucket
  
hunk.labels: keep replace keep keep keep keep
hunk.file_path: docker-compose.yaml
hunk.type: replace
file: package rardecode
  
  import "io"
  
  type bitReader interface {
  	readBits(n uint) (int, error) // read n bits of data
  	unreadBits(n uint)            // revert the reading of the last n bits read
  }
  
  type limitedBitReader struct {
  	br  bitReader
  	n   int
  	err error // error to return if br returns EOF before all n bits have been read
  }
  
  // limitBitReader returns a bitReader that reads from br and stops with io.EOF after n bits.
  // If br returns an io.EOF before reading n bits, err is returned.
  func limitBitReader(br bitReader, n int, err error) bitReader {
  	return &limitedBitReader{br, n, err}
  }
  
  func (l *limitedBitReader) readBits(n uint) (int, error) {
  	if int(n) > l.n {
  		return 0, io.EOF
  	}
  	v, err := l.br.readBits(n)
  	if err == nil {
  		l.n -= int(n)
  	} else if err == io.EOF {
  		err = l.err
  	}
  	return v, err
  }
  
  func (l *limitedBitReader) unreadBits(n uint) {
  	l.n += int(n)
  	l.br.unreadBits(n)
  }
  
  // rarBitReader wraps an io.ByteReader to perform various bit and byte
  // reading utility functions used in RAR file processing.
  type rarBitReader struct {
  	r io.ByteReader
  	v int
  	n uint
  }
  
  func (r *rarBitReader) reset(br io.ByteReader) {
  	r.r = br
  	r.n = 0
  	r.v = 0
  }
  
  func (r *rarBitReader) readBits(n uint) (int, error) {
  	for n > r.n {
  		c, err := r.r.ReadByte()
  		if err != nil {
  			return 0, err
  		}
  		r.v = r.v<<8 | int(c)
  		r.n += 8
  	}
  	r.n -= n
  	return (r.v >> r.n) & ((1 << n) - 1), nil
  }
  
  func (r *rarBitReader) unreadBits(n uint) {
  	r.n += n
  }
  
  // alignByte aligns the current bit reading input to the next byte boundary.
  func (r *rarBitReader) alignByte() {
  	r.n -= r.n % 8
  }
  
  // readUint32 reads a RAR V3 encoded uint32
  func (r *rarBitReader) readUint32() (uint32, error) {
  	n, err := r.readBits(2)
  	if err != nil {
  		return 0, err
  	}
  	if n != 1 {
  		n, err = r.readBits(4 << uint(n))
  		return uint32(n), err
  	}
  	n, err = r.readBits(4)
  	if err != nil {
  		return 0, err
  	}
  	if n == 0 {
  		n, err = r.readBits(8)
  		n |= -1 << 8
  		return uint32(n), err
  	}
  	nlow, err := r.readBits(4)
  	n = n<<4 | nlow
  	return uint32(n), err
  }
  
  func (r *rarBitReader) ReadByte() (byte, error) {
  	n, err := r.readBits(8)
  	return byte(n), err
  }
  
  // readFull reads len(p) bytes into p. If fewer bytes are read an error is returned.
  func (r *rarBitReader) readFull(p []byte) error {
  	for i := range p {
  		c, err := r.ReadByte()
  		if err != nil {
  			return err
  		}
  		p[i] = c
  	}
  	return nil
  }
  
  func newRarBitReader(r io.ByteReader) *rarBitReader {
  	return &rarBitReader{r: r}
  }
  