diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-09-15 21:27:55 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-15 21:27:55 +0300 |
| commit | 70c09627b307a57a94db64b92e461bb8ad1bc861 (patch) | |
| tree | ee64098e263e04afac513d9a5d60b4c6eabb128a /bitreader.go | |
| parent | change readme for LGPL v2.1 (diff) | |
| parent | revamped bitreader; with new functionality and bug fixes (diff) | |
| download | bitreader-70c09627b307a57a94db64b92e461bb8ad1bc861.tar.gz bitreader-70c09627b307a57a94db64b92e461bb8ad1bc861.tar.bz2 bitreader-70c09627b307a57a94db64b92e461bb8ad1bc861.zip | |
Merge pull request #4 from pektezol/v2
revamped bitreader; with new functionality and bug fixes
Diffstat (limited to 'bitreader.go')
| -rw-r--r-- | bitreader.go | 419 |
1 files changed, 273 insertions, 146 deletions
diff --git a/bitreader.go b/bitreader.go index 89c3526..d8f9f89 100644 --- a/bitreader.go +++ b/bitreader.go | |||
| @@ -1,46 +1,72 @@ | |||
| 1 | // BitReader is a simple bit reader with big/little-endian support for golang. | 1 | // BitReader is a simple bit reader with big/little-endian support for golang. |
| 2 | // It can read stream data from an io.Reader; can read from os.File and a byte array with bytes.NewReader(array). | ||
| 3 | // Uses bitwise operations for v2. | ||
| 4 | // Supports reading up to 64 bits at one time. | ||
| 5 | // Includes wrapper functions for most used data types. | ||
| 6 | // Error checking on all but wrapper functions. | ||
| 7 | // Thanks to github.com/mlugg for the big help! | ||
| 8 | package bitreader | 2 | package bitreader |
| 9 | 3 | ||
| 10 | import ( | 4 | import ( |
| 5 | "bytes" | ||
| 6 | "errors" | ||
| 11 | "fmt" | 7 | "fmt" |
| 12 | "io" | 8 | "io" |
| 13 | "math" | 9 | "math" |
| 14 | ) | 10 | ) |
| 15 | 11 | ||
| 16 | // ReaderType is the main structure of our Reader. | 12 | // Reader is the main structure of our Reader. |
| 17 | // Whenever index == 0, we need to read a new byte from stream into curByte | 13 | // Whenever index == 0, we need to read a new byte from stream into currentByte |
| 18 | // | 14 | // |
| 19 | // stream io.Reader The underlying stream we're reading bytes from | 15 | // stream io.Reader The underlying stream we're reading bytes from |
| 20 | // index uint18 The current index into the byte [0-7] | 16 | // index uint8 The current index into the byte [0-7] |
| 21 | // curByte byte The byte we're currently reading from | 17 | // currentByte byte The byte we're currently reading from |
| 22 | // le bool Whether to read in little-endian order | 18 | // le bool Whether to read in little-endian order or not |
| 23 | type ReaderType struct { | 19 | type Reader struct { |
| 24 | stream io.Reader | 20 | stream io.Reader |
| 25 | index uint8 | 21 | index uint8 |
| 26 | curByte byte | 22 | currentByte byte |
| 27 | le bool | 23 | littleEndian bool |
| 28 | } | 24 | } |
| 29 | 25 | ||
| 30 | // Reader is the main constructor that creates the ReaderType object | 26 | // NewReader is the main constructor that creates the Reader object |
| 31 | // with stream data and little-endian state. | 27 | // with stream reader data and little-endian state. |
| 32 | func Reader(stream io.Reader, le bool) *ReaderType { | 28 | func NewReader(stream io.Reader, littleEndian bool) *Reader { |
| 33 | return &ReaderType{ | 29 | return &Reader{ |
| 34 | stream: stream, | 30 | stream: stream, |
| 35 | index: 0, | 31 | index: 0, |
| 36 | curByte: 0, // Initial value doesn't matter, it'll be read as soon as we try to read any bits | 32 | currentByte: 0, |
| 37 | le: le, | 33 | littleEndian: littleEndian, |
| 38 | } | 34 | } |
| 39 | } | 35 | } |
| 40 | 36 | ||
| 41 | // TryReadBool is a wrapper function that gets the state of 1-bit, | 37 | // NewReaderFromBytes is the main constructor that creates the Reader object |
| 42 | // returns true if 1, false if 0. Panics on error. | 38 | // with stream byte data and little-endian state. |
| 43 | func (reader *ReaderType) TryReadBool() bool { | 39 | func NewReaderFromBytes(stream []byte, littleEndian bool) *Reader { |
| 40 | return &Reader{ | ||
| 41 | stream: bytes.NewReader(stream), | ||
| 42 | index: 0, | ||
| 43 | currentByte: 0, | ||
| 44 | littleEndian: littleEndian, | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | // Fork is a function that copies the original reader into a new reader | ||
| 49 | // with all of its current values. | ||
| 50 | func (reader *Reader) Fork() (*Reader, error) { | ||
| 51 | originalIndex := reader.index | ||
| 52 | originalCurrentByte := reader.currentByte | ||
| 53 | byteStream, err := io.ReadAll(reader.stream) | ||
| 54 | if err != nil { | ||
| 55 | return nil, err // Will only happen when there's no memory, lol | ||
| 56 | } | ||
| 57 | reader.stream = bytes.NewReader(byteStream) | ||
| 58 | return &Reader{ | ||
| 59 | stream: bytes.NewReader(byteStream), | ||
| 60 | index: uint8(originalIndex), | ||
| 61 | currentByte: originalCurrentByte, | ||
| 62 | littleEndian: reader.littleEndian, | ||
| 63 | }, nil | ||
| 64 | } | ||
| 65 | |||
| 66 | // TryReadBool is a wrapper function that gets the state of 1-bit. | ||
| 67 | // | ||
| 68 | // Returns true if 1, false if 0. Panics on overflow. | ||
| 69 | func (reader *Reader) TryReadBool() bool { | ||
| 44 | flag, err := reader.ReadBool() | 70 | flag, err := reader.ReadBool() |
| 45 | if err != nil { | 71 | if err != nil { |
| 46 | panic(err) | 72 | panic(err) |
| @@ -49,8 +75,9 @@ func (reader *ReaderType) TryReadBool() bool { | |||
| 49 | } | 75 | } |
| 50 | 76 | ||
| 51 | // TryReadInt1 is a wrapper function that returns the value of 1-bit. | 77 | // TryReadInt1 is a wrapper function that returns the value of 1-bit. |
| 52 | // Returns type uint8. Panics on error. | 78 | // |
| 53 | func (reader *ReaderType) TryReadInt1() uint8 { | 79 | // Returns type uint8. Panics on overflow. |
| 80 | func (reader *Reader) TryReadInt1() uint8 { | ||
| 54 | value, err := reader.ReadBits(1) | 81 | value, err := reader.ReadBits(1) |
| 55 | if err != nil { | 82 | if err != nil { |
| 56 | panic(err) | 83 | panic(err) |
| @@ -58,9 +85,10 @@ func (reader *ReaderType) TryReadInt1() uint8 { | |||
| 58 | return uint8(value) | 85 | return uint8(value) |
| 59 | } | 86 | } |
| 60 | 87 | ||
| 61 | // TryReadInt8 is a wrapper function that returns the value of 8-bits. | 88 | // TryReadUInt8 is a wrapper function that returns the value of 8-bits. |
| 62 | // Returns uint8. Panics on error. | 89 | // |
| 63 | func (reader *ReaderType) TryReadInt8() uint8 { | 90 | // Returns uint8. Panics on overflow. |
| 91 | func (reader *Reader) TryReadUInt8() uint8 { | ||
| 64 | value, err := reader.ReadBits(8) | 92 | value, err := reader.ReadBits(8) |
| 65 | if err != nil { | 93 | if err != nil { |
| 66 | panic(err) | 94 | panic(err) |
| @@ -68,9 +96,21 @@ func (reader *ReaderType) TryReadInt8() uint8 { | |||
| 68 | return uint8(value) | 96 | return uint8(value) |
| 69 | } | 97 | } |
| 70 | 98 | ||
| 71 | // TryReadInt16 is a wrapper function that returns the value of 16-bits. | 99 | // TryReadSInt8 is a wrapper function that returns the value of 8-bits. |
| 72 | // Returns uint16. Panics on error. | 100 | // |
| 73 | func (reader *ReaderType) TryReadInt16() uint16 { | 101 | // Returns int8. Panics on overflow. |
| 102 | func (reader *Reader) TryReadSInt8() int8 { | ||
| 103 | value, err := reader.ReadBits(8) | ||
| 104 | if err != nil { | ||
| 105 | panic(err) | ||
| 106 | } | ||
| 107 | return int8(value) | ||
| 108 | } | ||
| 109 | |||
| 110 | // TryReadUInt16 is a wrapper function that returns the value of 16-bits. | ||
| 111 | // | ||
| 112 | // Returns uint16. Panics on overflow. | ||
| 113 | func (reader *Reader) TryReadUInt16() uint16 { | ||
| 74 | value, err := reader.ReadBits(16) | 114 | value, err := reader.ReadBits(16) |
| 75 | if err != nil { | 115 | if err != nil { |
| 76 | panic(err) | 116 | panic(err) |
| @@ -78,9 +118,21 @@ func (reader *ReaderType) TryReadInt16() uint16 { | |||
| 78 | return uint16(value) | 118 | return uint16(value) |
| 79 | } | 119 | } |
| 80 | 120 | ||
| 81 | // TryReadInt32 is a wrapper function that returns the value of 32-bits. | 121 | // TryReadSInt16 is a wrapper function that returns the value of 16-bits. |
| 82 | // Returns uint32. Panics on error. | 122 | // |
| 83 | func (reader *ReaderType) TryReadInt32() uint32 { | 123 | // Returns uint16. Panics on overflow. |
| 124 | func (reader *Reader) TryReadSInt16() int16 { | ||
| 125 | value, err := reader.ReadBits(16) | ||
| 126 | if err != nil { | ||
| 127 | panic(err) | ||
| 128 | } | ||
| 129 | return int16(value) | ||
| 130 | } | ||
| 131 | |||
| 132 | // TryReadUInt32 is a wrapper function that returns the value of 32-bits. | ||
| 133 | // | ||
| 134 | // Returns uint32. Panics on overflow. | ||
| 135 | func (reader *Reader) TryReadUInt32() uint32 { | ||
| 84 | value, err := reader.ReadBits(32) | 136 | value, err := reader.ReadBits(32) |
| 85 | if err != nil { | 137 | if err != nil { |
| 86 | panic(err) | 138 | panic(err) |
| @@ -88,9 +140,21 @@ func (reader *ReaderType) TryReadInt32() uint32 { | |||
| 88 | return uint32(value) | 140 | return uint32(value) |
| 89 | } | 141 | } |
| 90 | 142 | ||
| 91 | // TryReadInt64 is a wrapper function that returns the value of 64-bits. | 143 | // TryReadSInt32 is a wrapper function that returns the value of 32-bits. |
| 92 | // Returns uint64. Panics on error. | 144 | // |
| 93 | func (reader *ReaderType) TryReadInt64() uint64 { | 145 | // Returns int32. Panics on overflow. |
| 146 | func (reader *Reader) TryReadSInt32() int32 { | ||
| 147 | value, err := reader.ReadBits(32) | ||
| 148 | if err != nil { | ||
| 149 | panic(err) | ||
| 150 | } | ||
| 151 | return int32(value) | ||
| 152 | } | ||
| 153 | |||
| 154 | // TryReadUInt64 is a wrapper function that returns the value of 64-bits. | ||
| 155 | // | ||
| 156 | // Returns uint64. Panics on overflow. | ||
| 157 | func (reader *Reader) TryReadUInt64() uint64 { | ||
| 94 | value, err := reader.ReadBits(64) | 158 | value, err := reader.ReadBits(64) |
| 95 | if err != nil { | 159 | if err != nil { |
| 96 | panic(err) | 160 | panic(err) |
| @@ -98,9 +162,21 @@ func (reader *ReaderType) TryReadInt64() uint64 { | |||
| 98 | return value | 162 | return value |
| 99 | } | 163 | } |
| 100 | 164 | ||
| 165 | // TryReadSInt64 is a wrapper function that returns the value of 64-bits. | ||
| 166 | // | ||
| 167 | // Returns int64. Panics on overflow. | ||
| 168 | func (reader *Reader) TryReadSInt64() int64 { | ||
| 169 | value, err := reader.ReadBits(64) | ||
| 170 | if err != nil { | ||
| 171 | panic(err) | ||
| 172 | } | ||
| 173 | return int64(value) | ||
| 174 | } | ||
| 175 | |||
| 101 | // TryReadFloat32 is a wrapper function that returns the value of 32-bits. | 176 | // TryReadFloat32 is a wrapper function that returns the value of 32-bits. |
| 102 | // Returns float32. Panics on error. | 177 | // |
| 103 | func (reader *ReaderType) TryReadFloat32() float32 { | 178 | // Returns float32. Panics on overflow. |
| 179 | func (reader *Reader) TryReadFloat32() float32 { | ||
| 104 | value, err := reader.ReadBits(32) | 180 | value, err := reader.ReadBits(32) |
| 105 | if err != nil { | 181 | if err != nil { |
| 106 | panic(err) | 182 | panic(err) |
| @@ -109,8 +185,9 @@ func (reader *ReaderType) TryReadFloat32() float32 { | |||
| 109 | } | 185 | } |
| 110 | 186 | ||
| 111 | // TryReadFloat64 is a wrapper function that returns the value of 64-bits. | 187 | // TryReadFloat64 is a wrapper function that returns the value of 64-bits. |
| 112 | // Returns float64. Panics on error. | 188 | // |
| 113 | func (reader *ReaderType) TryReadFloat64() float64 { | 189 | // Returns float64. Panics on overflow. |
| 190 | func (reader *Reader) TryReadFloat64() float64 { | ||
| 114 | value, err := reader.ReadBits(64) | 191 | value, err := reader.ReadBits(64) |
| 115 | if err != nil { | 192 | if err != nil { |
| 116 | panic(err) | 193 | panic(err) |
| @@ -119,8 +196,9 @@ func (reader *ReaderType) TryReadFloat64() float64 { | |||
| 119 | } | 196 | } |
| 120 | 197 | ||
| 121 | // TryReadBits is a wrapper function that returns the value of bits specified in the parameter. | 198 | // TryReadBits is a wrapper function that returns the value of bits specified in the parameter. |
| 122 | // Returns uint64. Panics on error. | 199 | // |
| 123 | func (reader *ReaderType) TryReadBits(bits int) uint64 { | 200 | // Returns uint64. Panics on overflow. |
| 201 | func (reader *Reader) TryReadBits(bits int) uint64 { | ||
| 124 | value, err := reader.ReadBits(bits) | 202 | value, err := reader.ReadBits(bits) |
| 125 | if err != nil { | 203 | if err != nil { |
| 126 | panic(err) | 204 | panic(err) |
| @@ -129,8 +207,9 @@ func (reader *ReaderType) TryReadBits(bits int) uint64 { | |||
| 129 | } | 207 | } |
| 130 | 208 | ||
| 131 | // TryReadBytes is a wrapper function that returns the value of bits specified in the parameter. | 209 | // TryReadBytes is a wrapper function that returns the value of bits specified in the parameter. |
| 132 | // Returns uint64. Panics on error. | 210 | // |
| 133 | func (reader *ReaderType) TryReadBytes(bytes int) uint64 { | 211 | // Returns uint64. Panics on overflow. |
| 212 | func (reader *Reader) TryReadBytes(bytes int) uint64 { | ||
| 134 | value, err := reader.ReadBytes(bytes) | 213 | value, err := reader.ReadBytes(bytes) |
| 135 | if err != nil { | 214 | if err != nil { |
| 136 | panic(err) | 215 | panic(err) |
| @@ -140,21 +219,33 @@ func (reader *ReaderType) TryReadBytes(bytes int) uint64 { | |||
| 140 | 219 | ||
| 141 | // TryReadString is a wrapper function that returns the string | 220 | // TryReadString is a wrapper function that returns the string |
| 142 | // that is read until it is null-terminated. | 221 | // that is read until it is null-terminated. |
| 143 | func (reader *ReaderType) TryReadString() string { | 222 | // |
| 144 | text, _ := reader.ReadString() | 223 | // Returns string. Panics on overflow. |
| 224 | func (reader *Reader) TryReadString() string { | ||
| 225 | text, err := reader.ReadString() | ||
| 226 | if err != nil { | ||
| 227 | panic(err) | ||
| 228 | } | ||
| 145 | return text | 229 | return text |
| 146 | } | 230 | } |
| 147 | 231 | ||
| 148 | // TryReadStringLen is a wrapper function that returns the string | 232 | // TryReadStringLength is a wrapper function that returns the string |
| 149 | // that is read until the given length is reached or it is null-terminated. | 233 | // that is read until the given length is reached or it is null-terminated. |
| 150 | func (reader *ReaderType) TryReadStringLen(length int) string { | 234 | // |
| 151 | text, _ := reader.ReadStringLen(length) | 235 | // Returns string. Panics on overflow. |
| 236 | func (reader *Reader) TryReadStringLength(length int) string { | ||
| 237 | text, err := reader.ReadStringLength(length) | ||
| 238 | if err != nil { | ||
| 239 | panic(err) | ||
| 240 | } | ||
| 152 | return text | 241 | return text |
| 153 | } | 242 | } |
| 154 | 243 | ||
| 155 | // TryReadBytesToSlice is a wrapper function that reads the specified amount of bits | 244 | // TryReadBytesToSlice is a wrapper function that reads the specified amount of bits |
| 156 | // from the parameter and puts each bit into a slice and returns this slice. | 245 | // from the parameter and puts each bit into a slice and returns this slice. |
| 157 | func (reader *ReaderType) TryReadBitsToSlice(bits int) []byte { | 246 | // |
| 247 | // Returns []byte. Panics on overflow. | ||
| 248 | func (reader *Reader) TryReadBitsToSlice(bits int) []byte { | ||
| 158 | bytes := (bits / 8) | 249 | bytes := (bits / 8) |
| 159 | if bits%8 != 0 { | 250 | if bits%8 != 0 { |
| 160 | bytes++ | 251 | bytes++ |
| @@ -189,7 +280,9 @@ func (reader *ReaderType) TryReadBitsToSlice(bits int) []byte { | |||
| 189 | 280 | ||
| 190 | // TryReadBytesToSlice is a wrapper function that reads the specified amount of bytes | 281 | // TryReadBytesToSlice is a wrapper function that reads the specified amount of bytes |
| 191 | // from the parameter and puts each byte into a slice and returns this slice. | 282 | // from the parameter and puts each byte into a slice and returns this slice. |
| 192 | func (reader *ReaderType) TryReadBytesToSlice(bytes int) []byte { | 283 | // |
| 284 | // Returns []byte. Panics on overflow. | ||
| 285 | func (reader *Reader) TryReadBytesToSlice(bytes int) []byte { | ||
| 193 | var out []byte | 286 | var out []byte |
| 194 | for i := 0; i < bytes; i++ { | 287 | for i := 0; i < bytes; i++ { |
| 195 | val, err := reader.ReadBytes(1) | 288 | val, err := reader.ReadBytes(1) |
| @@ -201,42 +294,70 @@ func (reader *ReaderType) TryReadBytesToSlice(bytes int) []byte { | |||
| 201 | return out | 294 | return out |
| 202 | } | 295 | } |
| 203 | 296 | ||
| 204 | // SkipBits is a function that increases Reader index | 297 | // TryReadBytesToSlice is a wrapper function that reads the remaining bits |
| 205 | // based on given input bits number. | 298 | // left in the stream and returns the count of bits. |
| 299 | // | ||
| 300 | // Returns uint64. Panics on overflow. | ||
| 301 | func (reader *Reader) TryReadRemainingBits() uint64 { | ||
| 302 | bits, err := reader.ReadRemainingBits() | ||
| 303 | if err != nil { | ||
| 304 | panic(err) | ||
| 305 | } | ||
| 306 | return bits | ||
| 307 | } | ||
| 308 | |||
| 309 | // ReadBool is a function that reads one bit and returns the state, error | ||
| 310 | // based on the output. Returns the read value in a bool format. | ||
| 206 | // | 311 | // |
| 207 | // Returns an error if there are no remaining bits. | 312 | // Returns an error if there are no remaining bits. |
| 208 | func (reader *ReaderType) SkipBits(bits int) error { | 313 | func (reader *Reader) ReadBool() (bool, error) { |
| 209 | // Read as many raw bytes as we can | 314 | val, err := reader.readBit() |
| 210 | bytes := bits / 8 | ||
| 211 | buf := make([]byte, bytes) | ||
| 212 | _, err := reader.stream.Read(buf) | ||
| 213 | if err != nil { | 315 | if err != nil { |
| 214 | return err | 316 | return false, err |
| 215 | } | 317 | } |
| 216 | // The final read byte should be the new current byte | 318 | return val == 1, nil |
| 217 | if bytes > 0 { | 319 | } |
| 218 | reader.curByte = buf[bytes-1] | 320 | |
| 321 | // ReadBits is a function that reads the specified amount of bits | ||
| 322 | // from the parameter and returns the value, error | ||
| 323 | // based on the output. It can read up to 64 bits. Returns the read | ||
| 324 | // value in type uint64. | ||
| 325 | // | ||
| 326 | // Returns an error if there are no remaining bits. | ||
| 327 | func (reader *Reader) ReadBits(bits int) (uint64, error) { | ||
| 328 | if bits < 1 || bits > 64 { | ||
| 329 | return 0, errors.New("ReadBits(bits) ERROR: Bits number should be between 1 and 64") | ||
| 219 | } | 330 | } |
| 220 | // Read the extra bits | 331 | var val uint64 |
| 221 | for i := bytes * 8; i < bits; i++ { | 332 | for i := 0; i < bits; i++ { |
| 222 | _, err := reader.readBit() | 333 | bit, err := reader.readBit() |
| 223 | if err != nil { | 334 | if err != nil { |
| 224 | return err | 335 | return 0, err |
| 336 | } | ||
| 337 | if reader.littleEndian { | ||
| 338 | val |= uint64(bit) << i | ||
| 339 | } else { | ||
| 340 | val |= uint64(bit) << (bits - 1 - i) | ||
| 225 | } | 341 | } |
| 226 | } | 342 | } |
| 227 | return nil | 343 | return val, nil |
| 228 | } | 344 | } |
| 229 | 345 | ||
| 230 | // SkipBytes is a function that increases Reader index | 346 | // ReadBytes is a function that reads the specified amount of bytes |
| 231 | // based on given input bytes number. | 347 | // from the parameter and returns the value, error |
| 348 | // based on the output. It can read up to 8 bytes. Returns the read | ||
| 349 | // value in type uint64. | ||
| 232 | // | 350 | // |
| 233 | // Returns an error if there are no remaining bits. | 351 | // Returns an error if there are no remaining bits. |
| 234 | func (reader *ReaderType) SkipBytes(bytes int) error { | 352 | func (reader *Reader) ReadBytes(bytes int) (uint64, error) { |
| 235 | err := reader.SkipBits(bytes * 8) | 353 | if bytes < 1 || bytes > 8 { |
| 354 | return 0, errors.New("ReadBytes(bytes) ERROR: Bytes number should be between 1 and 8") | ||
| 355 | } | ||
| 356 | value, err := reader.ReadBits(bytes * 8) | ||
| 236 | if err != nil { | 357 | if err != nil { |
| 237 | return err | 358 | return 0, err |
| 238 | } | 359 | } |
| 239 | return nil | 360 | return value, nil |
| 240 | } | 361 | } |
| 241 | 362 | ||
| 242 | // ReadString is a function that reads every byte | 363 | // ReadString is a function that reads every byte |
| @@ -244,7 +365,7 @@ func (reader *ReaderType) SkipBytes(bytes int) error { | |||
| 244 | // string that is read until the null-termination. | 365 | // string that is read until the null-termination. |
| 245 | // | 366 | // |
| 246 | // Returns an error if there are no remaining bits. | 367 | // Returns an error if there are no remaining bits. |
| 247 | func (reader *ReaderType) ReadString() (string, error) { | 368 | func (reader *Reader) ReadString() (string, error) { |
| 248 | var out string | 369 | var out string |
| 249 | for { | 370 | for { |
| 250 | value, err := reader.ReadBytes(1) | 371 | value, err := reader.ReadBytes(1) |
| @@ -259,13 +380,13 @@ func (reader *ReaderType) ReadString() (string, error) { | |||
| 259 | return out, nil | 380 | return out, nil |
| 260 | } | 381 | } |
| 261 | 382 | ||
| 262 | // ReadStringLen is a function that reads every byte | 383 | // ReadStringLength is a function that reads every byte |
| 263 | // until the given length, or it is null-terminated (the byte is 0). | 384 | // until the given length, or it is null-terminated (the byte is 0). |
| 264 | // Returns the string that is read until the lenth or null-termination. | 385 | // Returns the string that is read until the lenth or null-termination. |
| 265 | // It will skip the remaining bytes if it is null-terminated. | 386 | // It will skip the remaining bytes if it is null-terminated. |
| 266 | // | 387 | // |
| 267 | // Returns an error if there are no remaining bits. | 388 | // Returns an error if there are no remaining bits. |
| 268 | func (reader *ReaderType) ReadStringLen(length int) (string, error) { | 389 | func (reader *Reader) ReadStringLength(length int) (string, error) { |
| 269 | var out string | 390 | var out string |
| 270 | for i := 0; i < length; i++ { | 391 | for i := 0; i < length; i++ { |
| 271 | value, err := reader.ReadBytes(1) | 392 | value, err := reader.ReadBytes(1) |
| @@ -281,54 +402,11 @@ func (reader *ReaderType) ReadStringLen(length int) (string, error) { | |||
| 281 | return out, nil | 402 | return out, nil |
| 282 | } | 403 | } |
| 283 | 404 | ||
| 284 | // ReadBits is a function that reads the specified amount of bits | ||
| 285 | // from the parameter and returns the value, error | ||
| 286 | // based on the output. It can read up to 64 bits. Returns the read | ||
| 287 | // value in type uint64. | ||
| 288 | // | ||
| 289 | // Returns an error if there are no remaining bits. | ||
| 290 | func (reader *ReaderType) ReadBits(bits int) (uint64, error) { | ||
| 291 | if bits < 1 || bits > 64 { | ||
| 292 | return 0, fmt.Errorf("ReadBits(bits) ERROR: Bits number should be between 1 and 64.") | ||
| 293 | } | ||
| 294 | var val uint64 | ||
| 295 | for i := 0; i < bits; i++ { | ||
| 296 | bit, err := reader.readBit() | ||
| 297 | if err != nil { | ||
| 298 | return 0, err | ||
| 299 | } | ||
| 300 | |||
| 301 | if reader.le { | ||
| 302 | val |= uint64(bit) << i | ||
| 303 | } else { | ||
| 304 | val |= uint64(bit) << (bits - 1 - i) | ||
| 305 | } | ||
| 306 | } | ||
| 307 | return val, nil | ||
| 308 | } | ||
| 309 | |||
| 310 | // ReadBytes is a function that reads the specified amount of bytes | ||
| 311 | // from the parameter and returns the value, error | ||
| 312 | // based on the output. It can read up to 8 bytes. Returns the read | ||
| 313 | // value in type uint64. | ||
| 314 | // | ||
| 315 | // Returns an error if there are no remaining bits. | ||
| 316 | func (reader *ReaderType) ReadBytes(bytes int) (uint64, error) { | ||
| 317 | if bytes < 1 || bytes > 8 { | ||
| 318 | return 0, fmt.Errorf("ReadBytes(bytes) ERROR: Bytes number should be between 1 and 8.") | ||
| 319 | } | ||
| 320 | value, err := reader.ReadBits(bytes * 8) | ||
| 321 | if err != nil { | ||
| 322 | return 0, err | ||
| 323 | } | ||
| 324 | return value, nil | ||
| 325 | } | ||
| 326 | |||
| 327 | // ReadBitsToSlice is a function that reads the specified amount of bits | 405 | // ReadBitsToSlice is a function that reads the specified amount of bits |
| 328 | // from the parameter and puts each bit into a slice and returns this slice. | 406 | // from the parameter and puts each bit into a slice and returns this slice. |
| 329 | // | 407 | // |
| 330 | // Returns an error if there are no remaining bits. | 408 | // Returns an error if there are no remaining bits. |
| 331 | func (reader *ReaderType) ReadBitsToSlice(bits int) ([]byte, error) { | 409 | func (reader *Reader) ReadBitsToSlice(bits int) ([]byte, error) { |
| 332 | bytes := (bits / 8) | 410 | bytes := (bits / 8) |
| 333 | if bits%8 != 0 { | 411 | if bits%8 != 0 { |
| 334 | bytes++ | 412 | bytes++ |
| @@ -365,7 +443,7 @@ func (reader *ReaderType) ReadBitsToSlice(bits int) ([]byte, error) { | |||
| 365 | // from the parameter and puts each byte into a slice and returns this slice. | 443 | // from the parameter and puts each byte into a slice and returns this slice. |
| 366 | // | 444 | // |
| 367 | // Returns an error if there are no remaining bytes. | 445 | // Returns an error if there are no remaining bytes. |
| 368 | func (reader *ReaderType) ReadBytesToSlice(bytes int) ([]byte, error) { | 446 | func (reader *Reader) ReadBytesToSlice(bytes int) ([]byte, error) { |
| 369 | var out []byte | 447 | var out []byte |
| 370 | for i := 0; i < bytes; i++ { | 448 | for i := 0; i < bytes; i++ { |
| 371 | val, err := reader.ReadBytes(1) | 449 | val, err := reader.ReadBytes(1) |
| @@ -377,35 +455,84 @@ func (reader *ReaderType) ReadBytesToSlice(bytes int) ([]byte, error) { | |||
| 377 | return out, nil | 455 | return out, nil |
| 378 | } | 456 | } |
| 379 | 457 | ||
| 380 | // ReadBool is a function that reads one bit and returns the state, error | 458 | // SkipBits is a function that increases Reader index |
| 381 | // based on the output. Returns the read value in a bool format. | 459 | // based on given input bits number. |
| 382 | // | 460 | // |
| 383 | // Returns an error if there are no remaining bits. | 461 | // Returns an error if there are no remaining bits. |
| 384 | func (reader *ReaderType) ReadBool() (bool, error) { | 462 | func (reader *Reader) SkipBits(bits int) error { |
| 385 | val, err := reader.readBit() | 463 | // Read as many raw bytes as we can |
| 464 | bytes := bits / 8 | ||
| 465 | if bytes > 0 { | ||
| 466 | buf := make([]byte, bytes) | ||
| 467 | _, err := reader.stream.Read(buf) | ||
| 468 | if err != nil { | ||
| 469 | return err | ||
| 470 | } | ||
| 471 | // The final read byte should be the new current byte | ||
| 472 | reader.currentByte = buf[bytes-1] | ||
| 473 | } | ||
| 474 | // Read the extra bits | ||
| 475 | for i := bytes * 8; i < bits; i++ { | ||
| 476 | _, err := reader.readBit() | ||
| 477 | if err != nil { | ||
| 478 | return err | ||
| 479 | } | ||
| 480 | } | ||
| 481 | return nil | ||
| 482 | } | ||
| 483 | |||
| 484 | // SkipBytes is a function that increases Reader index | ||
| 485 | // based on given input bytes number. | ||
| 486 | // | ||
| 487 | // Returns an error if there are no remaining bits. | ||
| 488 | func (reader *Reader) SkipBytes(bytes int) error { | ||
| 489 | err := reader.SkipBits(bytes * 8) | ||
| 386 | if err != nil { | 490 | if err != nil { |
| 387 | return false, err | 491 | return err |
| 388 | } | 492 | } |
| 389 | return val == 1, nil | 493 | return nil |
| 494 | } | ||
| 495 | |||
| 496 | // ReadRemainingBits is a function that reads the total amount of remaining bits in the stream. | ||
| 497 | // It first forks the original reader to check this count, so that it does not interfere with the original stream. | ||
| 498 | // | ||
| 499 | // Returns an error if there are no remaining bits. | ||
| 500 | func (reader *Reader) ReadRemainingBits() (uint64, error) { | ||
| 501 | newReader, err := reader.Fork() | ||
| 502 | if err != nil { | ||
| 503 | return 0, err | ||
| 504 | } | ||
| 505 | var bits uint64 = 0 | ||
| 506 | for { | ||
| 507 | err := newReader.SkipBits(1) | ||
| 508 | if err != nil { | ||
| 509 | break // EOF | ||
| 510 | } | ||
| 511 | fmt.Printf("%+v\n", newReader) | ||
| 512 | bits++ | ||
| 513 | } | ||
| 514 | return bits, nil | ||
| 390 | } | 515 | } |
| 391 | 516 | ||
| 392 | // readBit is a private function that reads a single bit from the stream. | 517 | // readBit is a private function that reads a single bit from the stream. |
| 393 | // This is the main function that makes us read stream data. | 518 | // This is the main function that makes us read stream data. |
| 394 | func (reader *ReaderType) readBit() (uint8, error) { | 519 | func (reader *Reader) readBit() (uint8, error) { |
| 395 | if reader.index == 0 { | 520 | if reader.index == 0 { |
| 396 | // Read a byte from stream into curByte | 521 | // Read a byte from stream into currentByte |
| 397 | buf := make([]byte, 1) | 522 | buffer := make([]byte, 1) |
| 398 | _, err := reader.stream.Read(buf) | 523 | // We are not checking for the n return value from stream.Read, because we are only reading 1 byte at a time. |
| 524 | // Meaning if an EOF happens with a 1 byte read, we dont have any extra byte reading anyways. | ||
| 525 | _, err := reader.stream.Read(buffer) | ||
| 399 | if err != nil { | 526 | if err != nil { |
| 400 | return 0, err | 527 | return 0, err |
| 401 | } | 528 | } |
| 402 | reader.curByte = buf[0] | 529 | reader.currentByte = buffer[0] |
| 403 | } | 530 | } |
| 404 | var val bool | 531 | var val bool |
| 405 | if reader.le { | 532 | if reader.littleEndian { |
| 406 | val = (reader.curByte & (1 << reader.index)) != 0 | 533 | val = (reader.currentByte & (1 << reader.index)) != 0 |
| 407 | } else { | 534 | } else { |
| 408 | val = (reader.curByte & (1 << (7 - reader.index))) != 0 | 535 | val = (reader.currentByte & (1 << (7 - reader.index))) != 0 |
| 409 | } | 536 | } |
| 410 | reader.index = (reader.index + 1) % 8 | 537 | reader.index = (reader.index + 1) % 8 |
| 411 | if val { | 538 | if val { |