// Copyright (c) 2018 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package gcs import ( "io" ) type bitWriter struct { bytes []byte p *byte // Pointer to last byte next byte // Next bit to write or skip } // writeOne writes a one bit to the bit stream. func (b *bitWriter) writeOne() { if b.next == 0 { b.bytes = append(b.bytes, 1<<7) b.p = &b.bytes[len(b.bytes)-1] b.next = 1 << 6 return } *b.p |= b.next b.next >>= 1 } // writeZero writes a zero bit to the bit stream. func (b *bitWriter) writeZero() { if b.next == 0 { b.bytes = append(b.bytes, 0) b.p = &b.bytes[len(b.bytes)-1] b.next = 1 << 6 return } b.next >>= 1 } // writeNBits writes n number of LSB bits of data to the bit stream in big // endian format. Panics if n > 64. func (b *bitWriter) writeNBits(data uint64, n uint) { if n > 64 { panic("gcs: cannot write more than 64 bits of a uint64") } data <<= 64 - n // If byte is partially written, fill the rest for n > 0 { if b.next == 0 { break } if data&(1<<63) != 0 { b.writeOne() } else { b.writeZero() } n-- data <<= 1 } if n == 0 { return } // Write 8 bits at a time. for n >= 8 { b.bytes = append(b.bytes, byte(data>>56)) n -= 8 data <<= 8 } // Write the remaining bits. for n > 0 { if data&(1<<63) != 0 { b.writeOne() } else { b.writeZero() } n-- data <<= 1 } } type bitReader struct { bytes []byte next byte // next bit to read in bytes[0] } func newBitReader(bitstream []byte) bitReader { return bitReader{ bytes: bitstream, next: 1 << 7, } } // readUnary returns the number of unread sequential one bits before the next // zero bit. Errors with io.EOF if no zero bits are encountered. func (b *bitReader) readUnary() (uint64, error) { var value uint64 for { if len(b.bytes) == 0 { return value, io.EOF } for b.next != 0 { bit := b.bytes[0] & b.next b.next >>= 1 if bit == 0 { return value, nil } value++ } b.bytes = b.bytes[1:] b.next = 1 << 7 } } // readNBits reads n number of LSB bits of data from the bit stream in big // endian format. Panics if n > 64. func (b *bitReader) readNBits(n uint) (uint64, error) { if n > 64 { panic("gcs: cannot read more than 64 bits as a uint64") } if n == 0 { return 0, nil } if len(b.bytes) == 0 { return 0, io.EOF } var value uint64 // If byte is partially read, read the rest if b.next != 1<<7 { for n > 0 { if b.next == 0 { b.next = 1 << 7 b.bytes = b.bytes[1:] break } n-- if b.bytes[0]&b.next != 0 { value |= 1 << n } b.next >>= 1 } } if n == 0 { return value, nil } // Read 8 bits at a time. for n >= 8 { if len(b.bytes) == 0 { return 0, io.EOF } n -= 8 value |= uint64(b.bytes[0]) << n b.bytes = b.bytes[1:] } if len(b.bytes) == 0 { if n != 0 { return 0, io.EOF } return value, nil } // Read the remaining bits. for n > 0 { n-- if b.bytes[0]&b.next != 0 { value |= 1 << n } b.next >>= 1 } return value, nil }