// 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" "os" ) // 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 os.Error // because the error handling was verbose. Instead, any error is kept and can // be checked afterwards. type bitReader struct { r byteReader n uint64 bits uint err os.Error } // bitReader needs to read bytes from an io.Reader. We attempt to cast the // given io.Reader to this interface and, if it doesn't already fit, we wrap in // a bufio.Reader. type byteReader interface { ReadByte() (byte, os.Error) } func newBitReader(r io.Reader) bitReader { byter, ok := r.(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 Error(). func (br *bitReader) ReadBits64(bits uint) (n uint64) { for bits > br.bits { b, err := br.r.ReadByte() if err == os.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) Error() os.Error { return br.err }