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
}
|