src/pkg/compress/bzip2/bit_reader.go - The Go Programming Language

Golang

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	}