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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
package bitreader
import (
"fmt"
"math/bits"
"strconv"
"strings"
)
type ReaderType struct {
data []byte // Reader data from a byte array
base int // Current reader byte location
index int // Current reader index
le bool // Little endian or big endian?
}
func Reader(data []byte, le bool) *ReaderType {
dataClone := data
if le {
for index, byteValue := range data {
dataClone[index] = bits.Reverse8(byteValue)
}
}
return &ReaderType{
data: dataClone,
base: 0,
index: 0,
le: le,
}
}
func (reader *ReaderType) SkipBits(bits int) error {
if bits <= 0 {
return fmt.Errorf("SkipBits Error: Bits value %d lower or equals than 0.", bits)
}
err := reader.checkAvailableBits(bits)
if err != nil {
return err
}
for reader.index+bits > 7 {
reader.base++
reader.index = 0
bits -= 8
}
reader.index += bits
return nil
}
func (reader *ReaderType) SkipBytes(bytes int) error {
err := reader.SkipBits(bytes * 8)
if err != nil {
return err
}
return nil
}
func (reader *ReaderType) ReadBits(bits int) (int, error) {
if bits <= 0 {
return -1, fmt.Errorf("ReadBits Error: Bits value %d lower or equals than 0.", bits)
}
if bits > 64 {
return -1, fmt.Errorf("ReadBits Error: Bits value %d higher than 64.", bits)
}
err := reader.checkAvailableBits(bits)
if err != nil {
return -1, err
}
if reader.le {
var output string
// Go to last bit and read backwards from there
reader.base += bits / 8
reader.index += bits % 8
if reader.index > 7 {
reader.index -= 8
reader.base++
}
for i := 0; i < bits; i++ {
reader.index--
if reader.index < 0 {
reader.base--
reader.index = 7
}
binary := fmt.Sprintf("%08b", reader.data[reader.base])
binaryArr := strings.Split(binary, "")
output += binaryArr[reader.index]
}
// Return to last bit after reading
reader.base += bits / 8
reader.index += bits % 8
if reader.index > 7 {
reader.index -= 8
}
// Conversion of string binary to int
value, err := strconv.ParseUint(output, 2, 64)
if err != nil {
return -1, fmt.Errorf("%s", err)
}
return int(value), nil
} else {
var output string
for i := 0; i < bits; i++ {
binary := fmt.Sprintf("%08b", reader.data[reader.base])
binaryArr := strings.Split(binary, "")
output += binaryArr[reader.index]
reader.index++
if reader.index > 7 {
reader.base++
reader.index = 0
}
}
// Conversion of string binary to int
value, err := strconv.ParseUint(output, 2, 64)
if err != nil {
return -1, fmt.Errorf("%s", err)
}
return int(value), nil
}
}
func (reader *ReaderType) ReadBit() (bool, error) {
value, err := reader.ReadBits(1)
if err != nil {
return false, fmt.Errorf("ReadBit Error: %s", err)
}
return value != 0, nil
}
func (reader *ReaderType) checkAvailableBits(bits int) error {
availableBits := (len(reader.data)-reader.base)*8 - reader.index
if availableBits < bits {
return fmt.Errorf("BitReaderOutOfBounds: Wanted to read/skip %d bit(s) but only %d bit(s) is/are available.", bits, availableBits)
}
return nil
}
|