aboutsummaryrefslogtreecommitdiff
path: root/bitreader.go
diff options
context:
space:
mode:
authorBiSaXa <1669855+BiSaXa@users.noreply.github.com>2022-09-05 11:51:18 +0300
committerBiSaXa <1669855+BiSaXa@users.noreply.github.com>2022-09-05 11:51:18 +0300
commit42560481fa737e156c4b5e56561519b1be8468a9 (patch)
treec62fe4b443a33d1700cd139c685d8cd2be4ed378 /bitreader.go
parentMerge branch 'main' of https://github.com/BiSaXa/BitReader (diff)
downloadbitreader-42560481fa737e156c4b5e56561519b1be8468a9.tar.gz
bitreader-42560481fa737e156c4b5e56561519b1be8468a9.tar.bz2
bitreader-42560481fa737e156c4b5e56561519b1be8468a9.zip
v2 init
Diffstat (limited to '')
-rw-r--r--bitreader.go221
1 files changed, 128 insertions, 93 deletions
diff --git a/bitreader.go b/bitreader.go
index 06374b8..7e22ba6 100644
--- a/bitreader.go
+++ b/bitreader.go
@@ -1,48 +1,96 @@
1package bitreader 1// paksd
2package main
2 3
3import ( 4import (
4 "fmt" 5 "fmt"
5 "math/bits" 6 "io"
6 "strconv" 7 "math"
7 "strings"
8) 8)
9 9
10type ReaderType struct { 10type ReaderType struct {
11 data []byte // Reader data from a byte array 11 stream io.Reader // the underlying stream we're reading bytes from
12 base int // Current reader byte location 12 index uint8 // 0-7, the current index into the byte
13 index int // Current reader index 13 curByte byte // the byte we're currently reading from
14 le bool // Little endian or big endian? 14 le bool // whether to read in little-endian order
15 // Whenever index == 0, we need to read a new byte from stream into curByte
15} 16}
16 17
17func Reader(data []byte, le bool) *ReaderType { 18func Reader(stream io.Reader, le bool) *ReaderType {
18 dataClone := data
19 if le {
20 for index, byteValue := range data {
21 dataClone[index] = bits.Reverse8(byteValue)
22 }
23 }
24 return &ReaderType{ 19 return &ReaderType{
25 data: dataClone, 20 stream: stream,
26 base: 0, 21 index: 0,
27 index: 0, 22 curByte: 0, // initial value doesn't matter, it'll be read as soon as we try to read any bits
28 le: le, 23 le: le,
29 } 24 }
30} 25}
31 26
32func (reader *ReaderType) SkipBits(bits int) error { 27func (reader *ReaderType) TryReadInt8() (uint8, error) {
33 if bits <= 0 { 28 value, err := reader.ReadBits(8)
34 return fmt.Errorf("SkipBits Error: Bits value %d lower or equals than 0.", bits) 29 if err != nil {
30 return 0, err
31 }
32 return uint8(value), nil
33}
34
35func (reader *ReaderType) TryReadInt16() (uint16, error) {
36 value, err := reader.ReadBits(16)
37 if err != nil {
38 return 0, err
35 } 39 }
36 err := reader.checkAvailableBits(bits) 40 return uint16(value), nil
41}
42
43func (reader *ReaderType) TryReadInt32() (uint32, error) {
44 value, err := reader.ReadBits(32)
45 if err != nil {
46 return 0, err
47 }
48 return uint32(value), nil
49}
50
51func (reader *ReaderType) TryReadInt64() (uint64, error) {
52 value, err := reader.ReadBits(64)
53 if err != nil {
54 return 0, err
55 }
56 return value, nil
57}
58
59func (reader *ReaderType) TryReadFloat32() (float32, error) {
60 value, err := reader.ReadBits(32)
61 if err != nil {
62 return 0, err
63 }
64 return math.Float32frombits(uint32(value)), nil
65}
66
67func (reader *ReaderType) TryReadFloat64() (float64, error) {
68 value, err := reader.ReadBits(64)
69 if err != nil {
70 return 0, err
71 }
72 return math.Float64frombits(value), nil
73}
74
75func (reader *ReaderType) SkipBits(bits int) error {
76 // read as many raw bytes as we can
77 bytes := bits / 8
78 buf := make([]byte, bytes)
79 _, err := reader.stream.Read(buf)
37 if err != nil { 80 if err != nil {
38 return err 81 return err
39 } 82 }
40 for reader.index+bits > 7 { 83 // the final read byte should be the new current byte
41 reader.base++ 84 if bytes > 0 {
42 reader.index = 0 85 reader.curByte = buf[bytes-1]
43 bits -= 8 86 }
87 // read the extra bits
88 for i := bytes * 8; i < bits; i++ {
89 _, err := reader.readBit()
90 if err != nil {
91 return err
92 }
44 } 93 }
45 reader.index += bits
46 return nil 94 return nil
47} 95}
48 96
@@ -54,81 +102,68 @@ func (reader *ReaderType) SkipBytes(bytes int) error {
54 return nil 102 return nil
55} 103}
56 104
57func (reader *ReaderType) ReadBits(bits int) (int, error) { 105// Read up to 64 bits from the stream
58 if bits <= 0 { 106func (reader *ReaderType) ReadBits(bits int) (uint64, error) {
59 return -1, fmt.Errorf("ReadBits Error: Bits value %d lower or equals than 0.", bits) 107 if bits < 1 || bits > 64 {
60 } 108 return 0, fmt.Errorf("ReadBits(bits) ERROR: Bits number should be between 1 and 64.")
61 if bits > 64 {
62 return -1, fmt.Errorf("ReadBits Error: Bits value %d higher than 64.", bits)
63 } 109 }
64 err := reader.checkAvailableBits(bits) 110 var val uint64
65 if err != nil { 111 for i := 0; i < bits; i++ {
66 return -1, err 112 bit, err := reader.readBit()
67 }
68 if reader.le {
69 var output string
70 // Go to last bit and read backwards from there
71 reader.base += bits / 8
72 reader.index += bits % 8
73 if reader.index > 7 {
74 reader.index -= 8
75 reader.base++
76 }
77 for i := 0; i < bits; i++ {
78 reader.index--
79 if reader.index < 0 {
80 reader.base--
81 reader.index = 7
82 }
83 binary := fmt.Sprintf("%08b", reader.data[reader.base])
84 binaryArr := strings.Split(binary, "")
85 output += binaryArr[reader.index]
86 }
87 // Return to last bit after reading
88 reader.base += bits / 8
89 reader.index += bits % 8
90 if reader.index > 7 {
91 reader.index -= 8
92 }
93 // Conversion of string binary to int
94 value, err := strconv.ParseUint(output, 2, 64)
95 if err != nil { 113 if err != nil {
96 return -1, fmt.Errorf("%s", err) 114 return 0, err
97 } 115 }
98 return int(value), nil 116
99 } else { 117 if reader.le {
100 var output string 118 val |= uint64(bit) << i
101 for i := 0; i < bits; i++ { 119 } else {
102 binary := fmt.Sprintf("%08b", reader.data[reader.base]) 120 val |= uint64(bit) << (bits - 1 - i)
103 binaryArr := strings.Split(binary, "")
104 output += binaryArr[reader.index]
105 reader.index++
106 if reader.index > 7 {
107 reader.base++
108 reader.index = 0
109 }
110 }
111 // Conversion of string binary to int
112 value, err := strconv.ParseUint(output, 2, 64)
113 if err != nil {
114 return -1, fmt.Errorf("%s", err)
115 } 121 }
116 return int(value), nil
117 } 122 }
123 return val, nil
118} 124}
119 125
120func (reader *ReaderType) ReadBit() (bool, error) { 126func (reader *ReaderType) ReadBytes(bytes int) (uint64, error) {
121 value, err := reader.ReadBits(1) 127 if bytes < 1 || bytes > 8 {
128 return 0, fmt.Errorf("ReadBytes(bytes) ERROR: Bytes number should be between 1 and 8.")
129 }
130 value, err := reader.ReadBits(bytes * 8)
122 if err != nil { 131 if err != nil {
123 return false, fmt.Errorf("ReadBit Error: %s", err) 132 return 0, err
124 } 133 }
125 return value != 0, nil 134 return value, nil
126} 135}
127 136
128func (reader *ReaderType) checkAvailableBits(bits int) error { 137// Read a single bool from the stream
129 availableBits := (len(reader.data)-reader.base)*8 - reader.index 138func (reader *ReaderType) ReadBool() (bool, error) {
130 if availableBits < bits { 139 val, err := reader.readBit()
131 return fmt.Errorf("BitReaderOutOfBounds: Wanted to read/skip %d bit(s) but only %d bit(s) is/are available.", bits, availableBits) 140 if err != nil {
141 return false, err
142 }
143 return val == 1, nil
144}
145
146// Read a single bit from the stream
147func (reader *ReaderType) readBit() (uint8, error) {
148 if reader.index == 0 {
149 // read a byte from stream into curByte
150 buf := make([]byte, 1)
151 _, err := reader.stream.Read(buf)
152 if err != nil {
153 return 0, err
154 }
155 reader.curByte = buf[0]
156 }
157 var val bool
158 if reader.le {
159 val = (reader.curByte & (1 << reader.index)) != 0
160 } else {
161 val = (reader.curByte & (1 << (7 - reader.index))) != 0
162 }
163 reader.index = (reader.index + 1) % 8
164 if val {
165 return 1, nil
166 } else {
167 return 0, nil
132 } 168 }
133 return nil
134} 169}