blob: 5f63dd2d242a457ab37f230c6b9f7f79a4222710 (
plain)
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 | package bitio
import (
	"io"
)
type Writer interface {
	io.Writer
	// alignment:
	//  |-1-byte-block-|--------------|--------------|--------------|
	//  |<-offset->|<-------------------width---------------------->|
	WriteBits(data []byte, width uint) error
	WriteBit(bit bool) error
}
type writer struct {
	writer io.Writer
	octet  byte
	width  uint
}
func NewWriter(w io.Writer) Writer {
	return &writer{writer: w}
}
func (w *writer) Write(p []byte) (n int, err error) {
	if w.width != 0 {
		return 0, ErrInvalidAlignment
	}
	return w.writer.Write(p)
}
func (w *writer) WriteBits(data []byte, width uint) error {
	length := uint(len(data)) * 8
	offset := length - width
	for i := offset; i < length; i++ {
		oi := i / 8
		if err := w.WriteBit((data[oi]>>(7-i%8))&0x01 != 0); err != nil {
			return err
		}
	}
	return nil
}
func (w *writer) WriteBit(bit bool) error {
	if bit {
		w.octet |= 0x1 << (7 - w.width)
	}
	w.width++
	if w.width == 8 {
		if _, err := w.writer.Write([]byte{w.octet}); err != nil {
			return err
		}
		w.octet = 0x00
		w.width = 0
	}
	return nil
}
 |