// 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 bitReader.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) // // 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 }