aboutsummaryrefslogtreecommitdiff
path: root/bitreader.go
diff options
context:
space:
mode:
authorBiSaXa <1669855+BiSaXa@users.noreply.github.com>2022-09-04 01:07:28 +0300
committerBiSaXa <1669855+BiSaXa@users.noreply.github.com>2022-09-04 01:07:28 +0300
commit4a09f5844cb1649ecbdfec260628285cfcd640ec (patch)
tree7d1a4f31d0771467f0ae0db3444d3545fc3fbfe7 /bitreader.go
downloadbitreader-4a09f5844cb1649ecbdfec260628285cfcd640ec.tar.gz
bitreader-4a09f5844cb1649ecbdfec260628285cfcd640ec.tar.bz2
bitreader-4a09f5844cb1649ecbdfec260628285cfcd640ec.zip
init - first full version
Diffstat (limited to 'bitreader.go')
-rw-r--r--bitreader.go129
1 files changed, 129 insertions, 0 deletions
diff --git a/bitreader.go b/bitreader.go
new file mode 100644
index 0000000..9d9a273
--- /dev/null
+++ b/bitreader.go
@@ -0,0 +1,129 @@
1package main
2
3import (
4 "fmt"
5 "math/bits"
6 "strconv"
7 "strings"
8)
9
10type ReaderType struct {
11 data []byte
12 base int
13 index int
14 lsb bool
15}
16
17func Reader(data []byte) *ReaderType {
18 return &ReaderType{
19 data: data,
20 base: 0,
21 index: 0,
22 lsb: false,
23 }
24}
25
26func ReaderLSB(data []byte) *ReaderType {
27 dataReversed := data
28 for index, byteValue := range data {
29 dataReversed[index] = bits.Reverse8(byteValue)
30 }
31 return &ReaderType{
32 data: dataReversed,
33 base: 0,
34 index: 0,
35 lsb: true,
36 }
37}
38
39func (reader *ReaderType) SkipBits(bits int) error {
40 if bits <= 0 {
41 return fmt.Errorf("SkipBits Error: Bits value %d lower or equals than 0.", bits)
42 }
43 for reader.index+bits > 7 {
44 reader.base++
45 reader.index = 0
46 bits -= 8
47 }
48 reader.index += bits
49 return nil
50}
51
52func (reader *ReaderType) ReadBits32(bits int) (int, error) {
53 if bits <= 0 {
54 return -1, fmt.Errorf("ReadBits Error: Bits value %d lower or equals than 0.", bits)
55 }
56 if bits > 32 {
57 return -1, fmt.Errorf("ReadBits Error: Bits value %d higher than 32.", bits)
58 }
59 err := reader.checkAvailableBits(bits)
60 if err != nil {
61 return -1, err
62 }
63 if reader.lsb {
64 var output string
65 // Go to last bit and read backwards from there
66 reader.base += bits / 8
67 reader.index += bits % 8
68 if reader.index > 7 {
69 reader.index -= 8
70 reader.base++
71 }
72 for i := 0; i < bits; i++ {
73 reader.index--
74 if reader.index < 0 {
75 reader.base--
76 reader.index = 7
77 }
78 binary := fmt.Sprintf("%08b", reader.data[reader.base])
79 binaryArr := strings.Split(binary, "")
80 output += binaryArr[reader.index]
81 }
82 // Return to last bit after reading
83 reader.base += bits / 8
84 reader.index += bits % 8
85 if reader.index > 7 {
86 reader.index -= 8
87 }
88 // Conversion of string binary to int
89 value, err := strconv.ParseUint(output, 2, 32)
90 if err != nil {
91 return -1, fmt.Errorf("%s", err)
92 }
93 return int(value), nil
94 } else {
95 var output string
96 for i := 0; i < bits; i++ {
97 binary := fmt.Sprintf("%08b", reader.data[reader.base])
98 binaryArr := strings.Split(binary, "")
99 output += binaryArr[reader.index]
100 reader.index++
101 if reader.index > 7 {
102 reader.base++
103 reader.index = 0
104 }
105 }
106 // Conversion of string binary to int
107 value, err := strconv.ParseUint(output, 2, 32)
108 if err != nil {
109 return -1, fmt.Errorf("%s", err)
110 }
111 return int(value), nil
112 }
113}
114
115func (reader *ReaderType) ReadBit() (bool, error) {
116 value, err := reader.ReadBits32(1)
117 if err != nil {
118 return false, fmt.Errorf("ReadBit Error: %s", err)
119 }
120 return value != 0, nil
121}
122
123func (reader *ReaderType) checkAvailableBits(bits int) error {
124 availableBits := (len(reader.data)-reader.base)*8 - reader.index
125 if availableBits < bits {
126 return fmt.Errorf("BitReaderOutOfBounds: Wanted to read %d bit(s) but only %d bit(s) is/are available.", bits, availableBits)
127 }
128 return nil
129}