diff options
| author | BiSaXa <1669855+BiSaXa@users.noreply.github.com> | 2022-09-04 14:53:07 +0300 |
|---|---|---|
| committer | BiSaXa <1669855+BiSaXa@users.noreply.github.com> | 2022-09-04 14:53:07 +0300 |
| commit | a08480e8cd5df93a953323b400914520d5963660 (patch) | |
| tree | 964a157eb318d544967e8e20e42dd7c7526dc0c4 | |
| parent | specify little endian, easier reader construct (diff) | |
| download | bitreader-a08480e8cd5df93a953323b400914520d5963660.tar.gz bitreader-a08480e8cd5df93a953323b400914520d5963660.tar.bz2 bitreader-a08480e8cd5df93a953323b400914520d5963660.zip | |
added skipbytes, 64 bit support for readbits, new readme
| -rw-r--r-- | README.md | 37 | ||||
| -rw-r--r-- | bitreader.go | 26 | ||||
| -rw-r--r-- | bitreader_test.go | 13 |
3 files changed, 64 insertions, 12 deletions
| @@ -1 +1,38 @@ | |||
| 1 | # BitReader | 1 | # BitReader |
| 2 | A simple bit reader with big/little-endian support for golang.\ | ||
| 3 | Reads data from an existing byte array.\ | ||
| 4 | Uses string manipulation (for now).\ | ||
| 5 | Support reading up to 64 bits at one time.\ | ||
| 6 | Checking for overflowing the data. | ||
| 7 | |||
| 8 | ## Installation | ||
| 9 | ```bash | ||
| 10 | $ go get github.com/bisaxa/bitreader | ||
| 11 | ``` | ||
| 12 | |||
| 13 | ## Usage | ||
| 14 | |||
| 15 | ```go | ||
| 16 | import "github.com/bisaxa/bitreader" | ||
| 17 | |||
| 18 | // data: []byte Data to read from byte array | ||
| 19 | // le: bool Little-endian(true) or big-endian(false) state | ||
| 20 | reader := bitreader.Reader(data, le) | ||
| 21 | |||
| 22 | // read first bit | ||
| 23 | state, err := reader.ReadBit() | ||
| 24 | |||
| 25 | // skip bits/bytes | ||
| 26 | err := reader.SkipBits(8) | ||
| 27 | err := reader.SkipBytes(4) | ||
| 28 | |||
| 29 | // read bits | ||
| 30 | value, err := reader.ReadBits(11) | ||
| 31 | value, err := reader.ReadBits(64) // up to 64 bits | ||
| 32 | ``` | ||
| 33 | |||
| 34 | ## Error Handling | ||
| 35 | ReadBits(x), ReadBit(), SkipBits(x) and SkipBytes(x) functions returns an error message when they don't work as expected. It is advised to always handle errors. | ||
| 36 | |||
| 37 | ## License | ||
| 38 | This project is licensed under [MIT License](LICENSE). \ No newline at end of file | ||
diff --git a/bitreader.go b/bitreader.go index b105df7..635776b 100644 --- a/bitreader.go +++ b/bitreader.go | |||
| @@ -33,6 +33,10 @@ func (reader *ReaderType) SkipBits(bits int) error { | |||
| 33 | if bits <= 0 { | 33 | if bits <= 0 { |
| 34 | return fmt.Errorf("SkipBits Error: Bits value %d lower or equals than 0.", bits) | 34 | return fmt.Errorf("SkipBits Error: Bits value %d lower or equals than 0.", bits) |
| 35 | } | 35 | } |
| 36 | err := reader.checkAvailableBits(bits) | ||
| 37 | if err != nil { | ||
| 38 | return err | ||
| 39 | } | ||
| 36 | for reader.index+bits > 7 { | 40 | for reader.index+bits > 7 { |
| 37 | reader.base++ | 41 | reader.base++ |
| 38 | reader.index = 0 | 42 | reader.index = 0 |
| @@ -42,12 +46,20 @@ func (reader *ReaderType) SkipBits(bits int) error { | |||
| 42 | return nil | 46 | return nil |
| 43 | } | 47 | } |
| 44 | 48 | ||
| 45 | func (reader *ReaderType) ReadBits32(bits int) (int, error) { | 49 | func (reader *ReaderType) SkipBytes(bytes int) error { |
| 50 | err := reader.SkipBits(bytes * 8) | ||
| 51 | if err != nil { | ||
| 52 | return err | ||
| 53 | } | ||
| 54 | return nil | ||
| 55 | } | ||
| 56 | |||
| 57 | func (reader *ReaderType) ReadBits(bits int) (int, error) { | ||
| 46 | if bits <= 0 { | 58 | if bits <= 0 { |
| 47 | return -1, fmt.Errorf("ReadBits Error: Bits value %d lower or equals than 0.", bits) | 59 | return -1, fmt.Errorf("ReadBits Error: Bits value %d lower or equals than 0.", bits) |
| 48 | } | 60 | } |
| 49 | if bits > 32 { | 61 | if bits > 64 { |
| 50 | return -1, fmt.Errorf("ReadBits Error: Bits value %d higher than 32.", bits) | 62 | return -1, fmt.Errorf("ReadBits Error: Bits value %d higher than 64.", bits) |
| 51 | } | 63 | } |
| 52 | err := reader.checkAvailableBits(bits) | 64 | err := reader.checkAvailableBits(bits) |
| 53 | if err != nil { | 65 | if err != nil { |
| @@ -79,7 +91,7 @@ func (reader *ReaderType) ReadBits32(bits int) (int, error) { | |||
| 79 | reader.index -= 8 | 91 | reader.index -= 8 |
| 80 | } | 92 | } |
| 81 | // Conversion of string binary to int | 93 | // Conversion of string binary to int |
| 82 | value, err := strconv.ParseUint(output, 2, 32) | 94 | value, err := strconv.ParseUint(output, 2, 64) |
| 83 | if err != nil { | 95 | if err != nil { |
| 84 | return -1, fmt.Errorf("%s", err) | 96 | return -1, fmt.Errorf("%s", err) |
| 85 | } | 97 | } |
| @@ -97,7 +109,7 @@ func (reader *ReaderType) ReadBits32(bits int) (int, error) { | |||
| 97 | } | 109 | } |
| 98 | } | 110 | } |
| 99 | // Conversion of string binary to int | 111 | // Conversion of string binary to int |
| 100 | value, err := strconv.ParseUint(output, 2, 32) | 112 | value, err := strconv.ParseUint(output, 2, 64) |
| 101 | if err != nil { | 113 | if err != nil { |
| 102 | return -1, fmt.Errorf("%s", err) | 114 | return -1, fmt.Errorf("%s", err) |
| 103 | } | 115 | } |
| @@ -106,7 +118,7 @@ func (reader *ReaderType) ReadBits32(bits int) (int, error) { | |||
| 106 | } | 118 | } |
| 107 | 119 | ||
| 108 | func (reader *ReaderType) ReadBit() (bool, error) { | 120 | func (reader *ReaderType) ReadBit() (bool, error) { |
| 109 | value, err := reader.ReadBits32(1) | 121 | value, err := reader.ReadBits(1) |
| 110 | if err != nil { | 122 | if err != nil { |
| 111 | return false, fmt.Errorf("ReadBit Error: %s", err) | 123 | return false, fmt.Errorf("ReadBit Error: %s", err) |
| 112 | } | 124 | } |
| @@ -116,7 +128,7 @@ func (reader *ReaderType) ReadBit() (bool, error) { | |||
| 116 | func (reader *ReaderType) checkAvailableBits(bits int) error { | 128 | func (reader *ReaderType) checkAvailableBits(bits int) error { |
| 117 | availableBits := (len(reader.data)-reader.base)*8 - reader.index | 129 | availableBits := (len(reader.data)-reader.base)*8 - reader.index |
| 118 | if availableBits < bits { | 130 | if availableBits < bits { |
| 119 | return fmt.Errorf("BitReaderOutOfBounds: Wanted to read %d bit(s) but only %d bit(s) is/are available.", bits, availableBits) | 131 | return fmt.Errorf("BitReaderOutOfBounds: Wanted to read/skip %d bit(s) but only %d bit(s) is/are available.", bits, availableBits) |
| 120 | } | 132 | } |
| 121 | return nil | 133 | return nil |
| 122 | } | 134 | } |
diff --git a/bitreader_test.go b/bitreader_test.go index aed0930..ef421a8 100644 --- a/bitreader_test.go +++ b/bitreader_test.go | |||
| @@ -47,7 +47,7 @@ func TestReadBits32(t *testing.T) { | |||
| 47 | if err != nil { | 47 | if err != nil { |
| 48 | t.Fatal(err) | 48 | t.Fatal(err) |
| 49 | } | 49 | } |
| 50 | value, err := bitreader.ReadBits32(32) | 50 | value, err := bitreader.ReadBits(32) |
| 51 | if err != nil { | 51 | if err != nil { |
| 52 | t.Fatal(err) | 52 | t.Fatal(err) |
| 53 | } | 53 | } |
| @@ -57,12 +57,12 @@ func TestReadBits32(t *testing.T) { | |||
| 57 | } | 57 | } |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | func TestReadBits32LSB(t *testing.T) { | 60 | func TestReadBitsLE(t *testing.T) { |
| 61 | bitreader := Reader(TestArray[:], true) | 61 | bitreader := Reader(TestArray[:], true) |
| 62 | expected := []int{1720, 1768} // 11010111000, 11011101000 | 62 | expected := []int{1720, 1768} // 11010111000, 11011101000 |
| 63 | for i := range expected { | 63 | for i := range expected { |
| 64 | bitreader.ReadBit() | 64 | bitreader.ReadBit() |
| 65 | value, err := bitreader.ReadBits32(32) | 65 | value, err := bitreader.ReadBits(32) |
| 66 | if err != nil { | 66 | if err != nil { |
| 67 | t.Fatal(err) | 67 | t.Fatal(err) |
| 68 | } | 68 | } |
| @@ -75,7 +75,10 @@ func TestReadBits32LSB(t *testing.T) { | |||
| 75 | func TestSkipBits(t *testing.T) { | 75 | func TestSkipBits(t *testing.T) { |
| 76 | bitreader := Reader(TestArray[:], false) | 76 | bitreader := Reader(TestArray[:], false) |
| 77 | expected := []bool{true, true, false, true} //00001101 | 77 | expected := []bool{true, true, false, true} //00001101 |
| 78 | bitreader.SkipBits(12) | 78 | err := bitreader.SkipBits(12) |
| 79 | if err != nil { | ||
| 80 | t.Fatal(err) | ||
| 81 | } | ||
| 79 | for i := range expected { | 82 | for i := range expected { |
| 80 | value, err := bitreader.ReadBit() | 83 | value, err := bitreader.ReadBit() |
| 81 | if err != nil { | 84 | if err != nil { |
| @@ -87,7 +90,7 @@ func TestSkipBits(t *testing.T) { | |||
| 87 | } | 90 | } |
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | func TestSkipBitsLSB(t *testing.T) { | 93 | func TestSkipBitsLE(t *testing.T) { |
| 91 | bitreader := Reader(TestArray[:], true) | 94 | bitreader := Reader(TestArray[:], true) |
| 92 | expected := []bool{false, false, false, false} //10110000 | 95 | expected := []bool{false, false, false, false} //10110000 |
| 93 | bitreader.SkipBits(12) | 96 | bitreader.SkipBits(12) |