Skip to content

Commit 7d4a0cf

Browse files
committed
Initial Commit
0 parents  commit 7d4a0cf

10 files changed

+556
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# bitbuf-go
2+
3+
A direct port of [bitbuf](https://github.com/noocene/bitbuf) for Golang

bitbuf.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package bitbuf
2+
3+
type Size uint
4+
5+
type BitBuf interface {
6+
Advance(bits Size) error
7+
Read(dst []byte, bits Size) (Size, error)
8+
ReadAll(dst []byte, bits Size) error
9+
ReadAligned(dst []byte) Size
10+
ReadAlignedAll(out []byte) error
11+
ReadBool() (bool, error)
12+
ReadByte() (byte, error)
13+
Remaining() Size
14+
Len() Size
15+
}
16+
17+
type BitBufMut interface {
18+
Advance(bits Size) error
19+
Write(data []byte, bits Size) (Size, error)
20+
WriteAll(data []byte, bits Size) error
21+
WriteAligned(data []byte) Size
22+
WriteAlignedAll(data []byte) error
23+
WriteBool(data bool) error
24+
WriteByte(data byte) error
25+
Remaining() Size
26+
Len() Size
27+
}
28+
29+
type Drain interface {
30+
IntoInner() []byte
31+
DrainInto(buf BitBufMut) error
32+
AsBuf() BitBuf
33+
}
34+
35+
type Fill interface {
36+
IntoInner() []byte
37+
FillFrom(buf BitBuf) error
38+
AsBuf() BitBuf
39+
}

drain.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package bitbuf
2+
3+
func NewDrain(buf []byte) Drain {
4+
return drain{&transportContainer{
5+
buf: buf,
6+
length: 0,
7+
capacity: func(data []byte) Size {
8+
return Size(len(data)) * 8
9+
},
10+
}}
11+
}
12+
13+
func NewCappedDrain(buf []byte, cap Size) Drain {
14+
return drain{&transportContainer{
15+
buf: buf,
16+
length: 0,
17+
capacity: func(data []byte) Size {
18+
return cap
19+
},
20+
}}
21+
}
22+
23+
func (d drain) IntoInner() []byte {
24+
return d.buf
25+
}
26+
27+
func (d drain) DrainInto(to BitBufMut) error {
28+
capacity := d.capacity(d.buf)
29+
from := NewBitSlice(d.buf)
30+
err := from.Advance(d.length)
31+
if err != nil {
32+
panic(err)
33+
}
34+
35+
for true {
36+
if d.length < capacity {
37+
if to.Remaining() >= 8 && capacity-d.length >= 8 {
38+
val, err := from.ReadByte()
39+
if err != nil {
40+
panic(err)
41+
}
42+
err = to.WriteByte(val)
43+
if err != nil {
44+
panic(err)
45+
}
46+
d.length += 8
47+
} else {
48+
val, err := from.ReadBool()
49+
if err != nil {
50+
panic(err)
51+
}
52+
err = to.WriteBool(val)
53+
if err != nil {
54+
return InsufficientError{}
55+
}
56+
d.length++
57+
}
58+
} else {
59+
return nil
60+
}
61+
}
62+
return nil
63+
}
64+
65+
func (d drain) AsBuf() BitBuf {
66+
return NewBitSlice(d.buf)
67+
}

errors.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package bitbuf
2+
3+
type InsufficientError struct{}
4+
5+
func (e InsufficientError) Error() string {
6+
return "Insufficient"
7+
}
8+
9+
type OverflowError struct{}
10+
11+
func (e OverflowError) Error() string {
12+
return "Overflow"
13+
}

fill.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package bitbuf
2+
3+
func NewFill(buf []byte) Fill {
4+
return fill{&transportContainer{
5+
buf: buf,
6+
length: 0,
7+
capacity: func(data []byte) Size {
8+
return Size(len(data)) * 8
9+
},
10+
}}
11+
}
12+
13+
func NewCappedFill(buf []byte, cap Size) Fill {
14+
return fill{&transportContainer{
15+
buf: buf,
16+
length: 0,
17+
capacity: func(data []byte) Size {
18+
return cap
19+
},
20+
}}
21+
}
22+
23+
func (f fill) IntoInner() []byte {
24+
return f.buf
25+
}
26+
27+
func (f fill) FillFrom(from BitBuf) error {
28+
capacity := f.capacity(f.buf)
29+
to := NewBitSliceMut(f.buf)
30+
err := to.Advance(f.length)
31+
if err != nil {
32+
panic(err)
33+
}
34+
35+
for true {
36+
if f.length < capacity {
37+
if from.Remaining() >= 8 && capacity-f.length >= 8 {
38+
val, err := from.ReadByte()
39+
if err != nil {
40+
panic(err)
41+
}
42+
err = to.WriteByte(val)
43+
if err != nil {
44+
panic(err)
45+
}
46+
f.length += 8
47+
} else {
48+
val, err := from.ReadBool()
49+
if err != nil {
50+
panic(err)
51+
}
52+
err = to.WriteBool(val)
53+
if err != nil {
54+
return InsufficientError{}
55+
}
56+
f.length++
57+
}
58+
} else {
59+
return nil
60+
}
61+
}
62+
return nil
63+
}
64+
65+
func (f fill) AsBuf() BitBuf {
66+
return NewBitSlice(f.buf)
67+
}

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module github.com/cabaletta/bitbuf-go
2+
go 1.14

internal.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package bitbuf
2+
3+
// hake
4+
5+
type sliceContainer struct {
6+
data []byte
7+
offset byte
8+
length Size
9+
}
10+
11+
type transportContainer struct {
12+
buf []byte
13+
length Size
14+
capacity func([]byte) Size
15+
}
16+
17+
type bitSlice struct {
18+
*sliceContainer
19+
}
20+
21+
type bitSliceMut struct {
22+
*sliceContainer
23+
}
24+
25+
type drain struct {
26+
*transportContainer
27+
}
28+
29+
type fill struct {
30+
*transportContainer
31+
}

0 commit comments

Comments
 (0)