• Stars
    star
    220
  • Rank 173,990 (Top 4 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 8 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Optimized bit-level Reader and Writer for Go.

bitio

Build Status Go Reference Go Report Card codecov

Package bitio provides an optimized bit-level Reader and Writer for Go.

You can use Reader.ReadBits() to read arbitrary number of bits from an io.Reader and return it as an uint64, and Writer.WriteBits() to write arbitrary number of bits of an uint64 value to an io.Writer.

Both Reader and Writer also provide optimized methods for reading / writing 1 bit of information in the form of a bool value: Reader.ReadBool() and Writer.WriteBool(). These make this package ideal for compression algorithms that use Huffman coding for example, where decision whether to step left or right in the Huffman tree is the most frequent operation.

Reader and Writer give a bit-level view of the underlying io.Reader and io.Writer, but they also provide a byte-level view (io.Reader and io.Writer) at the same time. This means you can also use the Reader.Read() and Writer.Write() methods to read and write slices of bytes. These will give you best performance if the underlying io.Reader and io.Writer are aligned to a byte boundary (else all the individual bytes are assembled from / spread to multiple bytes). You can ensure byte boundary alignment by calling the Align() method of Reader and Writer. As an extra, io.ByteReader and io.ByteWriter are also implemented.

Bit order

The more general highest-bits-first order is used. So for example if the input provides the bytes 0x8f and 0x55:

HEXA    8    f     5    5
BINARY  1000 1111  0101 0101
        aaaa bbbc  ccdd dddd

Then ReadBits will return the following values:

r := NewReader(bytes.NewBuffer([]byte{0x8f, 0x55}))
a, err := r.ReadBits(4) //   1000 = 0x08
b, err := r.ReadBits(3) //    111 = 0x07
c, err := r.ReadBits(3) //    101 = 0x05
d, err := r.ReadBits(6) // 010101 = 0x15

Writing the above values would result in the same sequence of bytes:

b := &bytes.Buffer{}
w := NewWriter(b)
err := w.WriteBits(0x08, 4)
err = w.WriteBits(0x07, 3)
err = w.WriteBits(0x05, 3)
err = w.WriteBits(0x15, 6)
err = w.Close()
// b will hold the bytes: 0x8f and 0x55

Error handling

All ReadXXX() and WriteXXX() methods return an error which you are expected to handle. For convenience, there are also matching TryReadXXX() and TryWriteXXX() methods which do not return an error. Instead they store the (first) error in the Reader.TryError / Writer.TryError field which you can inspect later. These TryXXX() methods are a no-op if a TryError has been encountered before, so it's safe to call multiple TryXXX() methods and defer the error checking.

For example:

r := NewReader(bytes.NewBuffer([]byte{0x8f, 0x55}))
a := r.TryReadBits(4) //   1000 = 0x08
b := r.TryReadBits(3) //    111 = 0x07
c := r.TryReadBits(3) //    101 = 0x05
d := r.TryReadBits(6) // 010101 = 0x15
if r.TryError != nil {
    // Handle error
}

This allows you to easily convert the result of individual ReadBits(), like this:

r := NewReader(bytes.NewBuffer([]byte{0x8f, 0x55}))
a := byte(r.TryReadBits(4))   //   1000 = 0x08
b := int32(r.TryReadBits(3))  //    111 = 0x07
c := int64(r.TryReadBits(3))  //    101 = 0x05
d := uint16(r.TryReadBits(6)) // 010101 = 0x15
if r.TryError != nil {
    // Handle error
}

And similarly:

b := &bytes.Buffer{}
w := NewWriter(b)
w.TryWriteBits(0x08, 4)
w.TryWriteBits(0x07, 3)
w.TryWriteBits(0x05, 3)
w.TryWriteBits(0x15, 6)
if w.TryError != nil {
    // Handle error
}
err = w.Close()
// b will hold the bytes: 0x8f and 0x55

Number of processed bits

For performance reasons, Reader and Writer do not keep track of the number of read or written bits. If you happen to need the total number of processed bits, you may use the CountReader and CountWriter types which have identical API to that of Reader and Writer, but they also maintain the number of processed bits which you can query using the BitsCount field.

LICENSE

Licensed under either of

at your option.

More Repositories

1

gowut

Go Web UI Toolkit - Public Releases and Development
Go
289
star
2

scelight

The source code of the Scelight project with all its modules.
Java
117
star
3

session

Go session management for web servers (including support for Google App Engine - GAE).
Go
111
star
4

gox

Minimalistic extension to Go. It means to be a complement to the standard library.
Go
109
star
5

mjpeg

MJPEG video writer implementation in Go.
Go
100
star
6

screp

StarCraft - Brood War replay parser
Go
73
star
7

minquery

MongoDB / mgo query that supports efficient pagination (cursors to continue listing documents where we left off).
Go
60
star
8

s2prot

Decoder/parser of Blizzard's StarCraft II replay file format (*.SC2Replay)
Go
49
star
9

backscanner

A scanner similar to bufio.Scanner, but it reads and returns lines in reverse order, starting at a given position and going backward.
Go
46
star
10

sc2gears

The COMPLETE (!) source code of the Sc2gears universe (Sc2gears app + Sc2gears Database + web-based parsing engine - bundled in an Eclipse project).
Java
33
star
11

mpq

Decoder/parser of Blizzard's MPQ archive file format
Go
32
star
12

huffman

Huffman coding implementation in Go (Huffman tree, Symbol table, Huffman Reader + Writer).
Go
27
star
13

golab

This is the reincarnation of my gophergala/golab: a 2D labyrinth game.
Go
26
star
14

gog

General extensions to the Go language, requiring generics
Go
20
star
15

kvcache

Simple, optimized, embedded, persistent (file-based) key-value cache
Go
13
star
16

shutdown

Tiny Go package to help controlling app shutdown and graceful termination of goroutines.
Go
8
star
17

bwhf

StarCraft BroodWar Hacker Finder, anti-hack, replay analyzer-organizer and utility tool
Java
7
star
18

abcsort

Go string sorting library that uses a custom, user-defined alphabet
Go
6
star
19

balls-sdl

Bouncing balls demo (using SDL2)
Go
5
star
20

bombermen

Bombermen is a computer arcade game based on the classic Dynablaster and Atomic bomberman specified to be highly configurable and playable.
Java
5
star
21

srtgears

Subtitle engine for reading, manipulating / transforming and saving subtitle files.
Go
5
star
22

mighty

Lightweight extension to Go's testing package.
Go
4
star
23

recursion

Recursive algorithms.
Java
3
star
24

v

V is a minimalist 3D labyrinth applet demo being less than 4 KB, 3D graphics and rendering coded manually
Java
3
star
25

gowut.dev

Go Web UI Toolkit - Development
Go
2
star
26

java-fishing

Fishing is a 2D skill game.
Java
1
star
27

abdracommander

A 2-pane file manager written in Java
Java
1
star
28

authn

Passwordless, email based authentication with MongoDB store.
Go
1
star
29

balls-wde

Bouncing balls demo (using go.wde)
Go
1
star
30

gaesession

Google App Engine (GAE) support for github.com/icza/session
Go
1
star
31

4kraft

4KB StarCraft like Java applet game
Java
1
star