github.com/la5nta/wl2k-go@v0.11.8/lzhuf/bit_reader.go (about)

     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 lzhuf
     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 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  	// This 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  }