Source file src/pkg/compress/bzip2/bit_reader.go
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 byteReader 18 n uint64 19 bits uint 20 err error 21 } 22 23 // bitReader needs to read bytes from an io.Reader. We attempt to convert the 24 // given io.Reader to this interface and, if it doesn't already fit, we wrap in 25 // a bufio.Reader. 26 type byteReader interface { 27 ReadByte() (byte, error) 28 } 29 30 func newBitReader(r io.Reader) bitReader { 31 byter, ok := r.(byteReader) 32 if !ok { 33 byter = bufio.NewReader(r) 34 } 35 return bitReader{r: byter} 36 } 37 38 // ReadBits64 reads the given number of bits and returns them in the 39 // least-significant part of a uint64. In the event of an error, it returns 0 40 // and the error can be obtained by calling Err(). 41 func (br *bitReader) ReadBits64(bits uint) (n uint64) { 42 for bits > br.bits { 43 b, err := br.r.ReadByte() 44 if err == io.EOF { 45 err = io.ErrUnexpectedEOF 46 } 47 if err != nil { 48 br.err = err 49 return 0 50 } 51 br.n <<= 8 52 br.n |= uint64(b) 53 br.bits += 8 54 } 55 56 // br.n looks like this (assuming that br.bits = 14 and bits = 6): 57 // Bit: 111111 58 // 5432109876543210 59 // 60 // (6 bits, the desired output) 61 // |-----| 62 // V V 63 // 0101101101001110 64 // ^ ^ 65 // |------------| 66 // br.bits (num valid bits) 67 // 68 // This the next line right shifts the desired bits into the 69 // least-significant places and masks off anything above. 70 n = (br.n >> (br.bits - bits)) & ((1 << bits) - 1) 71 br.bits -= bits 72 return 73 } 74 75 func (br *bitReader) ReadBits(bits uint) (n int) { 76 n64 := br.ReadBits64(bits) 77 return int(n64) 78 } 79 80 func (br *bitReader) ReadBit() bool { 81 n := br.ReadBits(1) 82 return n != 0 83 } 84 85 func (br *bitReader) Err() error { 86 return br.err 87 }