diff options
| author | BiSaXa <1669855+BiSaXa@users.noreply.github.com> | 2022-09-11 10:06:12 +0300 |
|---|---|---|
| committer | BiSaXa <1669855+BiSaXa@users.noreply.github.com> | 2022-09-11 10:06:12 +0300 |
| commit | d05afc7acbec130e313587225bebe26c3a023449 (patch) | |
| tree | 33805127591d6394ff1116bc02d7d6d59165fff5 | |
| parent | added tryreadbool and tryreadint1 (diff) | |
| download | bitreader-d05afc7acbec130e313587225bebe26c3a023449.tar.gz bitreader-d05afc7acbec130e313587225bebe26c3a023449.tar.bz2 bitreader-d05afc7acbec130e313587225bebe26c3a023449.zip | |
added go doc
| -rw-r--r-- | bitreader.go | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/bitreader.go b/bitreader.go index 568f4f7..3fbc221 100644 --- a/bitreader.go +++ b/bitreader.go | |||
| @@ -1,4 +1,10 @@ | |||
| 1 | // paksd | 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! | ||
| 2 | package bitreader | 8 | package bitreader |
| 3 | 9 | ||
| 4 | import ( | 10 | import ( |
| @@ -7,23 +13,28 @@ import ( | |||
| 7 | "math" | 13 | "math" |
| 8 | ) | 14 | ) |
| 9 | 15 | ||
| 16 | // ReaderType is the main structure of our Reader. | ||
| 17 | // Whenever index == 0, we need to read a new byte from stream into curByte | ||
| 10 | type ReaderType struct { | 18 | type ReaderType struct { |
| 11 | stream io.Reader // the underlying stream we're reading bytes from | 19 | stream io.Reader // The underlying stream we're reading bytes from |
| 12 | index uint8 // 0-7, the current index into the byte | 20 | index uint8 // The current index into the byte [0-7] |
| 13 | curByte byte // the byte we're currently reading from | 21 | curByte byte // The byte we're currently reading from |
| 14 | le bool // whether to read in little-endian order | 22 | le bool // Whether to read in little-endian order |
| 15 | // Whenever index == 0, we need to read a new byte from stream into curByte | ||
| 16 | } | 23 | } |
| 17 | 24 | ||
| 25 | // Reader is the main constructor that creates the ReaderType object | ||
| 26 | // with stream data and little-endian state. | ||
| 18 | func Reader(stream io.Reader, le bool) *ReaderType { | 27 | func Reader(stream io.Reader, le bool) *ReaderType { |
| 19 | return &ReaderType{ | 28 | return &ReaderType{ |
| 20 | stream: stream, | 29 | stream: stream, |
| 21 | index: 0, | 30 | index: 0, |
| 22 | curByte: 0, // initial value doesn't matter, it'll be read as soon as we try to read any bits | 31 | curByte: 0, // Initial value doesn't matter, it'll be read as soon as we try to read any bits |
| 23 | le: le, | 32 | le: le, |
| 24 | } | 33 | } |
| 25 | } | 34 | } |
| 26 | 35 | ||
| 36 | // TryReadBool is a wrapper function that gets the state of 1-bit, | ||
| 37 | // returns true if 1, false if 0. Panics on error. | ||
| 27 | func (reader *ReaderType) TryReadBool() bool { | 38 | func (reader *ReaderType) TryReadBool() bool { |
| 28 | flag, err := reader.ReadBool() | 39 | flag, err := reader.ReadBool() |
| 29 | if err != nil { | 40 | if err != nil { |
| @@ -32,6 +43,8 @@ func (reader *ReaderType) TryReadBool() bool { | |||
| 32 | return flag | 43 | return flag |
| 33 | } | 44 | } |
| 34 | 45 | ||
| 46 | // TryReadInt1 is a wrapper function that returns the value of 1-bit. | ||
| 47 | // Returns type uint8. Panics on error. | ||
| 35 | func (reader *ReaderType) TryReadInt1() uint8 { | 48 | func (reader *ReaderType) TryReadInt1() uint8 { |
| 36 | value, err := reader.ReadBits(1) | 49 | value, err := reader.ReadBits(1) |
| 37 | if err != nil { | 50 | if err != nil { |
| @@ -40,6 +53,8 @@ func (reader *ReaderType) TryReadInt1() uint8 { | |||
| 40 | return uint8(value) | 53 | return uint8(value) |
| 41 | } | 54 | } |
| 42 | 55 | ||
| 56 | // TryReadInt8 is a wrapper function that returns the value of 8-bits. | ||
| 57 | // Returns uint8. Panics on error. | ||
| 43 | func (reader *ReaderType) TryReadInt8() uint8 { | 58 | func (reader *ReaderType) TryReadInt8() uint8 { |
| 44 | value, err := reader.ReadBits(8) | 59 | value, err := reader.ReadBits(8) |
| 45 | if err != nil { | 60 | if err != nil { |
| @@ -48,6 +63,8 @@ func (reader *ReaderType) TryReadInt8() uint8 { | |||
| 48 | return uint8(value) | 63 | return uint8(value) |
| 49 | } | 64 | } |
| 50 | 65 | ||
| 66 | // TryReadInt16 is a wrapper function that returns the value of 16-bits. | ||
| 67 | // Returns uint16. Panics on error. | ||
| 51 | func (reader *ReaderType) TryReadInt16() uint16 { | 68 | func (reader *ReaderType) TryReadInt16() uint16 { |
| 52 | value, err := reader.ReadBits(16) | 69 | value, err := reader.ReadBits(16) |
| 53 | if err != nil { | 70 | if err != nil { |
| @@ -56,6 +73,8 @@ func (reader *ReaderType) TryReadInt16() uint16 { | |||
| 56 | return uint16(value) | 73 | return uint16(value) |
| 57 | } | 74 | } |
| 58 | 75 | ||
| 76 | // TryReadInt32 is a wrapper function that returns the value of 32-bits. | ||
| 77 | // Returns uint32. Panics on error. | ||
| 59 | func (reader *ReaderType) TryReadInt32() uint32 { | 78 | func (reader *ReaderType) TryReadInt32() uint32 { |
| 60 | value, err := reader.ReadBits(32) | 79 | value, err := reader.ReadBits(32) |
| 61 | if err != nil { | 80 | if err != nil { |
| @@ -64,6 +83,8 @@ func (reader *ReaderType) TryReadInt32() uint32 { | |||
| 64 | return uint32(value) | 83 | return uint32(value) |
| 65 | } | 84 | } |
| 66 | 85 | ||
| 86 | // TryReadInt64 is a wrapper function that returns the value of 64-bits. | ||
| 87 | // Returns uint64. Panics on error. | ||
| 67 | func (reader *ReaderType) TryReadInt64() uint64 { | 88 | func (reader *ReaderType) TryReadInt64() uint64 { |
| 68 | value, err := reader.ReadBits(64) | 89 | value, err := reader.ReadBits(64) |
| 69 | if err != nil { | 90 | if err != nil { |
| @@ -72,6 +93,8 @@ func (reader *ReaderType) TryReadInt64() uint64 { | |||
| 72 | return value | 93 | return value |
| 73 | } | 94 | } |
| 74 | 95 | ||
| 96 | // TryReadFloat32 is a wrapper function that returns the value of 32-bits. | ||
| 97 | // Returns float32. Panics on error. | ||
| 75 | func (reader *ReaderType) TryReadFloat32() float32 { | 98 | func (reader *ReaderType) TryReadFloat32() float32 { |
| 76 | value, err := reader.ReadBits(32) | 99 | value, err := reader.ReadBits(32) |
| 77 | if err != nil { | 100 | if err != nil { |
| @@ -80,6 +103,8 @@ func (reader *ReaderType) TryReadFloat32() float32 { | |||
| 80 | return math.Float32frombits(uint32(value)) | 103 | return math.Float32frombits(uint32(value)) |
| 81 | } | 104 | } |
| 82 | 105 | ||
| 106 | // TryReadFloat64 is a wrapper function that returns the value of 64-bits. | ||
| 107 | // Returns float64. Panics on error. | ||
| 83 | func (reader *ReaderType) TryReadFloat64() float64 { | 108 | func (reader *ReaderType) TryReadFloat64() float64 { |
| 84 | value, err := reader.ReadBits(64) | 109 | value, err := reader.ReadBits(64) |
| 85 | if err != nil { | 110 | if err != nil { |
| @@ -88,19 +113,22 @@ func (reader *ReaderType) TryReadFloat64() float64 { | |||
| 88 | return math.Float64frombits(value) | 113 | return math.Float64frombits(value) |
| 89 | } | 114 | } |
| 90 | 115 | ||
| 116 | // SkipBits is a function that increases Reader index | ||
| 117 | // based on given input bits number. Returns an error | ||
| 118 | // if there are no remaining bits. | ||
| 91 | func (reader *ReaderType) SkipBits(bits int) error { | 119 | func (reader *ReaderType) SkipBits(bits int) error { |
| 92 | // read as many raw bytes as we can | 120 | // Read as many raw bytes as we can |
| 93 | bytes := bits / 8 | 121 | bytes := bits / 8 |
| 94 | buf := make([]byte, bytes) | 122 | buf := make([]byte, bytes) |
| 95 | _, err := reader.stream.Read(buf) | 123 | _, err := reader.stream.Read(buf) |
| 96 | if err != nil { | 124 | if err != nil { |
| 97 | return err | 125 | return err |
| 98 | } | 126 | } |
| 99 | // the final read byte should be the new current byte | 127 | // The final read byte should be the new current byte |
| 100 | if bytes > 0 { | 128 | if bytes > 0 { |
| 101 | reader.curByte = buf[bytes-1] | 129 | reader.curByte = buf[bytes-1] |
| 102 | } | 130 | } |
| 103 | // read the extra bits | 131 | // Read the extra bits |
| 104 | for i := bytes * 8; i < bits; i++ { | 132 | for i := bytes * 8; i < bits; i++ { |
| 105 | _, err := reader.readBit() | 133 | _, err := reader.readBit() |
| 106 | if err != nil { | 134 | if err != nil { |
| @@ -110,6 +138,9 @@ func (reader *ReaderType) SkipBits(bits int) error { | |||
| 110 | return nil | 138 | return nil |
| 111 | } | 139 | } |
| 112 | 140 | ||
| 141 | // SkipBytes is a function that increases Reader index | ||
| 142 | // based on given input bytes number. Returns an error | ||
| 143 | // if there are no remaining bits. | ||
| 113 | func (reader *ReaderType) SkipBytes(bytes int) error { | 144 | func (reader *ReaderType) SkipBytes(bytes int) error { |
| 114 | err := reader.SkipBits(bytes * 8) | 145 | err := reader.SkipBits(bytes * 8) |
| 115 | if err != nil { | 146 | if err != nil { |
| @@ -118,7 +149,12 @@ func (reader *ReaderType) SkipBytes(bytes int) error { | |||
| 118 | return nil | 149 | return nil |
| 119 | } | 150 | } |
| 120 | 151 | ||
| 121 | // Read up to 64 bits from the stream | 152 | // ReadBits is a function that reads the specified amount of bits |
| 153 | // specified in the parameter and returns the value, error | ||
| 154 | // based on the output. It can read up to 64 bits. Returns the read | ||
| 155 | // value in type uint64. | ||
| 156 | // | ||
| 157 | // Returns an error if there are no remaining bits. | ||
| 122 | func (reader *ReaderType) ReadBits(bits int) (uint64, error) { | 158 | func (reader *ReaderType) ReadBits(bits int) (uint64, error) { |
| 123 | if bits < 1 || bits > 64 { | 159 | if bits < 1 || bits > 64 { |
| 124 | return 0, fmt.Errorf("ReadBits(bits) ERROR: Bits number should be between 1 and 64.") | 160 | return 0, fmt.Errorf("ReadBits(bits) ERROR: Bits number should be between 1 and 64.") |
| @@ -139,6 +175,12 @@ func (reader *ReaderType) ReadBits(bits int) (uint64, error) { | |||
| 139 | return val, nil | 175 | return val, nil |
| 140 | } | 176 | } |
| 141 | 177 | ||
| 178 | // ReadBytes is a function that reads the specified amount of bytes | ||
| 179 | // specified in the parameter and returns the value, error | ||
| 180 | // based on the output. It can read up to 8 bytes. Returns the read | ||
| 181 | // value in type uint64. | ||
| 182 | // | ||
| 183 | // Returns an error if there are no remaining bits. | ||
| 142 | func (reader *ReaderType) ReadBytes(bytes int) (uint64, error) { | 184 | func (reader *ReaderType) ReadBytes(bytes int) (uint64, error) { |
| 143 | if bytes < 1 || bytes > 8 { | 185 | if bytes < 1 || bytes > 8 { |
| 144 | return 0, fmt.Errorf("ReadBytes(bytes) ERROR: Bytes number should be between 1 and 8.") | 186 | return 0, fmt.Errorf("ReadBytes(bytes) ERROR: Bytes number should be between 1 and 8.") |
| @@ -150,7 +192,10 @@ func (reader *ReaderType) ReadBytes(bytes int) (uint64, error) { | |||
| 150 | return value, nil | 192 | return value, nil |
| 151 | } | 193 | } |
| 152 | 194 | ||
| 153 | // Read a single bool from the stream | 195 | // ReadBool is a function that reads one bit and returns the state, error |
| 196 | // based on the output. Returns the read value in a bool format. | ||
| 197 | // | ||
| 198 | // Returns an error if there are no remaining bits. | ||
| 154 | func (reader *ReaderType) ReadBool() (bool, error) { | 199 | func (reader *ReaderType) ReadBool() (bool, error) { |
| 155 | val, err := reader.readBit() | 200 | val, err := reader.readBit() |
| 156 | if err != nil { | 201 | if err != nil { |
| @@ -159,10 +204,11 @@ func (reader *ReaderType) ReadBool() (bool, error) { | |||
| 159 | return val == 1, nil | 204 | return val == 1, nil |
| 160 | } | 205 | } |
| 161 | 206 | ||
| 162 | // Read a single bit from the stream | 207 | // readBit is a private function that reads a single bit from the stream. |
| 208 | // This is the main function that makes us read stream data. | ||
| 163 | func (reader *ReaderType) readBit() (uint8, error) { | 209 | func (reader *ReaderType) readBit() (uint8, error) { |
| 164 | if reader.index == 0 { | 210 | if reader.index == 0 { |
| 165 | // read a byte from stream into curByte | 211 | // Read a byte from stream into curByte |
| 166 | buf := make([]byte, 1) | 212 | buf := make([]byte, 1) |
| 167 | _, err := reader.stream.Read(buf) | 213 | _, err := reader.stream.Read(buf) |
| 168 | if err != nil { | 214 | if err != nil { |