bitstream

package module
v0.0.0-...-e7599a5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2023 License: MIT Imports: 4 Imported by: 0

README

bitstream-go

A practical, high-performance, and easy-to-use bit stream reader/writer for golang.

  • Type aware (you don't need type castings to fit into your type)
  • Endianess aware (Little endian support is still work in progress)

Forked from https://github.com/bearmini/bitstream-go

Added functions to implement little endian reads

Usage

Reader

package main

import (
	"bytes"
	"fmt"
	"log"

	"github.com/Resaec/bitstream-go"
)

func main() {
	// binary expression:
	// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
	data := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}

	// Reader
	r := bitstream.NewReader(bytes.NewReader(data), nil)

	// read a single bit
	bit0, err := r.ReadBit()
	if err != nil {
		log.Fatalf("%+v", err)
	}
	fmt.Printf("bit: %1b\n", bit0)

	// read 2 bits
	bit1to2, err := r.ReadNBitsAsUint8(2)
	if err != nil {
		log.Fatalf("%+v", err)
	}
	fmt.Printf("bits: %02b\n", bit1to2)

	// read 10 bits as big endian
	bit3to12, err := r.ReadNBitsAsUint16BE(10)
	if err != nil {
		log.Fatalf("%+v", err)
	}
	fmt.Printf("bits: %010b\n", bit3to12)

	// read 20 bits as big endian
	bit13to32, err := r.ReadNBitsAsUint32BE(20)
	if err != nil {
		log.Fatalf("%+v", err)
	}
	fmt.Printf("bits: %020b\n", bit13to32)

	// Output:
	// bit: 0
	// bits: 00
	// bits: 0000100100
	// bits: 01101000101011001111
}

Writer

package main

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"log"

	"github.com/Resaec/bitstream-go"
)

func main() {
	dst := bytes.NewBuffer([]byte{})

	// Writer
	w := bitstream.NewWriter(dst)

	// Write a single bit `1`
	err := w.WriteBit(1)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	// Write a bool value as a bit (true: 1, false: 0)
	err = w.WriteBool(false)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	// Write 2 bits `10`
	err = w.WriteNBitsOfUint8(2, 0x02)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	// Write 8 bits `0101 0011`
	err = w.WriteUint8(0x53)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	// Write 10 bits `11 0010 1101`
	err = w.WriteNBitsOfUint16BE(10, 0x032d)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	// Write 16 bits `0000 1111 0101 1010`
	err = w.WriteUint16BE(0x0f5a)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	w.Flush()

	// we have written the following bits:
	// 1
	//  0
	//   10
	//      0101 0011
	//                1100 1011 01
	//                            00 0011 1101 0110 10
	// 1010 0101 0011 1100 1011 0100 0011 1101 0110 10xx

	fmt.Printf("%s", hex.EncodeToString(dst.Bytes()))
	// Output:
	// a53cb43d68
}

Documentation

Index

Examples

Constants

View Source
const (
	DefaultBufferSize = 1024
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ReadOptions

type ReadOptions struct {
	AlignRight bool // If true, returned value will be aligned to right (default: align to left)
	PadOne     bool // If true, returned value will be padded with '1' instead of '0' (default: pad with '0')
}

ReadOptions is a set of options to read bits from the bit stream.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader is a bit stream reader. It does not have io.Reader interface.

Example
// binary expression:
// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
data := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}

// Reader
r := bitstream.NewReader(bytes.NewReader(data), nil)

// read a single bit
bit0, err := r.ReadBit()
if err != nil {
	log.Fatalf("%+v", err)
}
fmt.Printf("bit: %1b\n", bit0)

// read 2 bits
bit1to2, err := r.ReadNBitsAsUint8(2)
if err != nil {
	log.Fatalf("%+v", err)
}
fmt.Printf("bits: %02b\n", bit1to2)

// read 10 bits as big endian
bit3to12, err := r.ReadNBitsAsUint16BE(10)
if err != nil {
	log.Fatalf("%+v", err)
}
fmt.Printf("bits: %010b\n", bit3to12)

// read 20 bits as big endian
bit13to32, err := r.ReadNBitsAsUint32BE(20)
if err != nil {
	log.Fatalf("%+v", err)
}
fmt.Printf("bits: %020b\n", bit13to32)
Output:

bit: 0
bits: 00
bits: 0000100100
bits: 01101000101011001111

func NewReader

func NewReader(src io.Reader, opt *ReaderOptions) *Reader

NewReader creates a new Reader instance with options.

func (*Reader) ConsumedBytes

func (r *Reader) ConsumedBytes() uint

ConsumedBytes returns a number of bytes that has been consumed.

func (*Reader) ReadBit

func (r *Reader) ReadBit() (byte, error)

ReadBit reads a single bit from the bit stream. The bit read from the stream will be set in the LSB of the return value.

func (*Reader) ReadBool

func (r *Reader) ReadBool() (bool, error)

ReadBool reads a single bit from the bit stream and return it as a bool.

func (*Reader) ReadNBits

func (r *Reader) ReadNBits(nBits uint8, opt *ReadOptions) ([]byte, error)

ReadNBits reads `nBits` bits from the bit stream and returns it as a slice of bytes. If `nBits` == 0, this function always returns nil.

func (*Reader) ReadNBitsAsInt32BE

func (r *Reader) ReadNBitsAsInt32BE(nBits uint8) (int32, error)

ReadNBitsAsInt32BE reads `nBits` bits as a big endian signed integer from the bit stream and returns it in int32 (LSB aligned). MSB is a sign bit. `nBits` must be less than or equal to 32, otherwise returns an error. If `nBits` == 0, this function always returns 0.

func (*Reader) ReadNBitsAsUint16BE

func (r *Reader) ReadNBitsAsUint16BE(nBits uint8) (uint16, error)

ReadNBitsAsUint16BE reads `nBits` bits as a big endian unsigned integer from the bit stream and returns it in uint16 (LSB aligned). `nBits` must be less than or equal to 16, otherwise returns an error. If `nBits` == 0, this function always returns 0.

func (*Reader) ReadNBitsAsUint32BE

func (r *Reader) ReadNBitsAsUint32BE(nBits uint8) (uint32, error)

ReadNBitsAsUint32BE reads `nBits` bits as a big endian unsigned integer from the bit stream and returns it in uint32 (LSB aligned). `nBits` must be less than or equal to 32, otherwise returns an error. If `nBits` == 0, this function always returns 0.

func (*Reader) ReadNBitsAsUint64BE

func (r *Reader) ReadNBitsAsUint64BE(nBits uint8) (uint64, error)

ReadNBitsAsUint64BE reads `nBits` bits as a big endian unsigned integer from the bit stream and returns it in uint64 (LSB aligned). `nBits` must be less than or equal to 64, otherwise returns an error. If `nBits` == 0, this function always returns 0.

func (*Reader) ReadNBitsAsUint8

func (r *Reader) ReadNBitsAsUint8(nBits uint8) (uint8, error)

ReadNBitsAsUint8 reads `nBits` bits as a unsigned integer from the bit stream and returns it in uint8 (LSB aligned). `nBits` must be less than or equal to 8, otherwise returns an error. If `nBits` == 0, this function always returns 0.

func (*Reader) ReadUint16

func (r *Reader) ReadUint16() (val uint16, err error)

ReadUint16 reads 16 bits as a unsigned integer from the bit stream and returns it in uint16.

func (*Reader) ReadUint16BE

func (r *Reader) ReadUint16BE() (uint16, error)

ReadUint16BE reads 16 bits as a big endian unsigned integer from the bit stream and returns it in uint16.

func (*Reader) ReadUint32

func (r *Reader) ReadUint32() (val uint32, err error)

ReadUint32 reads 32 bits as a unsigned integer from the bit stream and returns it in uint32.

func (*Reader) ReadUint32BE

func (r *Reader) ReadUint32BE() (uint32, error)

ReadUint32BE reads 32 bits as a big endian unsigned integer from the bit stream and returns it in uint32.

func (*Reader) ReadUint64

func (r *Reader) ReadUint64() (val uint64, err error)

ReadUint64 reads 64 bits as a unsigned integer from the bit stream and returns it in uint64.

func (*Reader) ReadUint64BE

func (r *Reader) ReadUint64BE() (uint64, error)

ReadUint64BE reads 64 bits as a big endian unsigned integer from the bit stream and returns it in uint64.

func (*Reader) ReadUint8

func (r *Reader) ReadUint8() (uint8, error)

ReadUint8 reads 8 bits from the bit stream and returns it in uint8.

type ReaderOptions

type ReaderOptions struct {
	BufferSize uint
}

ReaderOptions is a set of options for creating a Reader.

func (*ReaderOptions) GetBufferSize

func (opt *ReaderOptions) GetBufferSize() uint

GetBufferSize gets configured buffer size.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer is a bit stream writer. It does not have io.Writer interface

Example
dst := bytes.NewBuffer([]byte{})

// Writer
w := bitstream.NewWriter(dst)

// Write a single bit `1`
err := w.WriteBit(1)
if err != nil {
	log.Fatalf("%+v", err)
}

// Write a bool value as a bit (true: 1, false: 0)
err = w.WriteBool(false)
if err != nil {
	log.Fatalf("%+v", err)
}

// Write 2 bits `10`
err = w.WriteNBitsOfUint8(2, 0x02)
if err != nil {
	log.Fatalf("%+v", err)
}

// Write 8 bits `0101 0011`
err = w.WriteUint8(0x53)
if err != nil {
	log.Fatalf("%+v", err)
}

// Write 10 bits `11 0010 1101`
err = w.WriteNBitsOfUint16BE(10, 0x032d)
if err != nil {
	log.Fatalf("%+v", err)
}

// Write 16 bits `0000 1111 0101 1010`
err = w.WriteUint16BE(0x0f5a)
if err != nil {
	log.Fatalf("%+v", err)
}

w.Flush()

// we have written the following bits:
// 1
//  0
//   10
//      0101 0011
//                1100 1011 01
//                            00 0011 1101 0110 10
// 1010 0101 0011 1100 1011 0100 0011 1101 0110 10xx

fmt.Printf("%s", hex.EncodeToString(dst.Bytes()))
Output:

a53cb43d68

func NewWriter

func NewWriter(dst io.Writer) *Writer

NewWriter creates a new Writer instance.

func (*Writer) Flush

func (w *Writer) Flush() error

Flush ensures the bufferred bits (bits not writen to the stream because it has less than 8 bits) to the destination writer.

func (*Writer) WriteBit

func (w *Writer) WriteBit(bit uint8) error

WriteBit writes a single bit to the bit stream. Uses the LSB bit in `bit`.

func (*Writer) WriteBool

func (w *Writer) WriteBool(b bool) error

WriteBool writes a single bit to the bit stream. Write 1 if b is `true`, 0 otherwise.

func (*Writer) WriteNBits

func (w *Writer) WriteNBits(nBits uint, data []byte) error

WriteNBits writes specified number of bits of the bytes to the bit stream.

func (*Writer) WriteNBitsOfUint16BE

func (w *Writer) WriteNBitsOfUint16BE(nBits uint8, val uint16) error

WriteNBitsOfUint16 writes `nBits` bits to the bit stream. `nBits` must be less than or equal to 16, otherwise returns an error.

func (*Writer) WriteNBitsOfUint32BE

func (w *Writer) WriteNBitsOfUint32BE(nBits uint8, val uint32) error

WriteNBitsOfUint32 writes `nBits` bits to the bit stream. `nBits` must be less than or equal to 32, otherwise returns an error.

func (*Writer) WriteNBitsOfUint8

func (w *Writer) WriteNBitsOfUint8(nBits, val uint8) error

WriteNBitsOfUint8 writes `nBits` bits to the bit stream. `nBits` must be less than or equal to 8, otherwise returns an error.

This function uses n bits from `val`'s LSB. i.e.)

if you have the following status of bit stream before calling WriteNBitsOfUint8,
currByte: 0101xxxxb
currBitIndex: 3

and if you calls WriteNBitsOfUint8(3, 0xaa),
  where nBits == 3, val == 0xaa (10101010b)

WriteNBitsOfUint8 uses the 3 bits from `val`'s LSB, i.e.) xxxxx010b and as a result, status of the bit stream become:
currByte: 0101010xb (0101xxxxb | xxxx010xb)
currBitIndex: 0

func (*Writer) WriteUint16BE

func (w *Writer) WriteUint16BE(val uint16) error

WriteUint16 writes a uint16 value to the bit stream.

func (*Writer) WriteUint32BE

func (w *Writer) WriteUint32BE(val uint32) error

WriteUint32 writes a uint32 value to the bit stream.

func (*Writer) WriteUint8

func (w *Writer) WriteUint8(val uint8) error

WriteUint8 writes a uint8 value to the bit stream.

func (*Writer) WrittenBits

func (w *Writer) WrittenBits() uint

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL