bit_reader.mx raw

   1  // Copyright 2011 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package bzip2
   6  
   7  import (
   8  	"bufio"
   9  	"io"
  10  )
  11  
  12  // bitReader wraps an io.Reader and provides the ability to read values,
  13  // bit-by-bit, from it. Its Read* methods don't return the usual error
  14  // because the error handling was verbose. Instead, any error is kept and can
  15  // be checked afterwards.
  16  type bitReader struct {
  17  	r    io.ByteReader
  18  	n    uint64
  19  	bits uint
  20  	err  error
  21  }
  22  
  23  // newBitReader returns a new bitReader reading from r. If r is not
  24  // already an io.ByteReader, it will be converted via a bufio.Reader.
  25  func newBitReader(r io.Reader) bitReader {
  26  	byter, ok := r.(io.ByteReader)
  27  	if !ok {
  28  		byter = bufio.NewReader(r)
  29  	}
  30  	return bitReader{r: byter}
  31  }
  32  
  33  // ReadBits64 reads the given number of bits and returns them in the
  34  // least-significant part of a uint64. In the event of an error, it returns 0
  35  // and the error can be obtained by calling bitReader.Err().
  36  func (br *bitReader) ReadBits64(bits uint) (n uint64) {
  37  	for bits > br.bits {
  38  		b, err := br.r.ReadByte()
  39  		if err == io.EOF {
  40  			err = io.ErrUnexpectedEOF
  41  		}
  42  		if err != nil {
  43  			br.err = err
  44  			return 0
  45  		}
  46  		br.n <<= 8
  47  		br.n |= uint64(b)
  48  		br.bits += 8
  49  	}
  50  
  51  	// br.n looks like this (assuming that br.bits = 14 and bits = 6):
  52  	// Bit: 111111
  53  	//      5432109876543210
  54  	//
  55  	//         (6 bits, the desired output)
  56  	//        |-----|
  57  	//        V     V
  58  	//      0101101101001110
  59  	//        ^            ^
  60  	//        |------------|
  61  	//           br.bits (num valid bits)
  62  	//
  63  	// The next line right shifts the desired bits into the
  64  	// least-significant places and masks off anything above.
  65  	n = (br.n >> (br.bits - bits)) & ((1 << bits) - 1)
  66  	br.bits -= bits
  67  	return
  68  }
  69  
  70  func (br *bitReader) ReadBits(bits uint) (n int) {
  71  	n64 := br.ReadBits64(bits)
  72  	return int(n64)
  73  }
  74  
  75  func (br *bitReader) ReadBit() bool {
  76  	n := br.ReadBits(1)
  77  	return n != 0
  78  }
  79  
  80  func (br *bitReader) Err() error {
  81  	return br.err
  82  }
  83