golang bit_reader 代码
文件路径:/src/compress/bzip2/bit_reader.go
/ Copyright 2011 The Go Authors. All rights reserved.
/ Use of this source code is governed by a BSD-style
/ license that can be found in the LICENSE file.
package bzip2
import (
"bufio"
"io"
)
/ bitReader wraps an io.Reader and provides the ability to read values,
/ bit-by-bit, from it. Its Read* methods don't return the usual error
/ because the error handling was verbose. Instead, any error is kept and can
/ be checked afterwards.
type bitReader struct {
r io.ByteReader
n uint64
bits uint
err error
}
/ newBitReader returns a new bitReader reading from r. If r is not
/ already an io.ByteReader, it will be converted via a bufio.Reader.
func newBitReader(r io.Reader) bitReader {
byter, ok := r.(io.ByteReader)
if !ok {
byter = bufio.NewReader(r)
}
return bitReader{r: byter}
}
/ ReadBits64 reads the given number of bits and returns them in the
/ least-significant part of a uint64. In the event of an error, it returns 0
/ and the error can be obtained by calling Err().
func (br *bitReader) ReadBits64(bits uint) (n uint64) {
for bits > br.bits {
b, err := br.r.ReadByte()
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
if err != nil {
br.err = err
return 0
}
br.n <<= 8
br.n |= uint64(b)
br.bits += 8
}
/ br.n looks like this (assuming that br.bits = 14 and bits = 6):
/ Bit: 111111
/ 5432109876543210
/
/ (6 bits, the desired output)
/ |-----|
/ V V
/ 0101101101001110
/ ^ ^
/ |------------|
/ br.bits (num valid bits)
/
/ This the next line right shifts the desired bits into the
/ least-significant places and masks off anything above.
n = (br.n >> (br.bits - bits)) & ((1 << bits) - 1)
br.bits -= bits
return
}
func (br *bitReader) ReadBits(bits uint) (n int) {
n64 := br.ReadBits64(bits)
return int(n64)
}
func (br *bitReader) ReadBit() bool {
n := br.ReadBits(1)
return n != 0
}
func (br *bitReader) Err() error {
return br.err
}