From f628b40dc66467db2e299f115ea9bac75a297900 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Fri, 11 Nov 2022 08:59:19 +0300 Subject: add ReadBitsToSlice() function --- README.md | 16 +++++++++++----- bitreader.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1093153..2bc00e7 100644 --- a/README.md +++ b/README.md @@ -28,16 +28,22 @@ err := reader.SkipBits(8) err := reader.SkipBytes(4) // Read Bits/Bytes -value, err := reader.ReadBytes(4) -value, err := reader.ReadBits(64) // up to 64 bits +value, err := reader.ReadBytes(4) // up to 8 bytes +value, err := reader.ReadBits(64) // up to 64 bits // Read String -text, err := reader.ReadString() // null-terminated -text, err := reader.ReadStringLen(256) // length-specified +text, err := reader.ReadString() // null-terminated +text, err := reader.ReadStringLen(256) // length-specified + +// Read Bits/Bytes into Slice +arr, err := reader.ReadBitsToSlice(128) +arr, err := reader.ReadBytesToSlice(64) // Wrapper functions text := reader.TryReadString() // string text := reader.TryReadStringLen(64) // string +arr := reader.ReadBitsToSlice(128) // []byte +arr := reader.ReadBytesToSlice(64) // []byte state := reader.TryReadBool() // bool value := reader.TryReadInt1() // uint8 value := reader.TryReadInt8() // uint8 @@ -51,7 +57,7 @@ value := reader.TryReadBytes(8) // uint64 ``` ## Error Handling -ReadBits(x), ReadBytes(x), ReadBool(), ReadString(), ReadStringLen(x) SkipBits(x) and SkipBytes(x) functions returns an error message when they don't work as expected. It is advised to always handle errors. \ +ReadBits(x), ReadBytes(x), ReadBool(), ReadString(), ReadStringLen(x), ReadBitsToSlice(x), ReadBytesToSlice(x), SkipBits(x) and SkipBytes(x) functions returns an error message when they don't work as expected. It is advised to always handle errors. \ Wrapper functions, however, only returns the value and panics if an error is encountered. ## Bug Report / Feature Request diff --git a/bitreader.go b/bitreader.go index b9ac772..5c7dc04 100644 --- a/bitreader.go +++ b/bitreader.go @@ -152,6 +152,29 @@ func (reader *ReaderType) TryReadStringLen(length int) string { return text } +// TryReadBytesToSlice is a wrapper function that reads the specified amount of bits +// from the parameter and puts each bit into a slice and returns this slice. +func (reader *ReaderType) TryReadBitsToSlice(bits int) []byte { + bytes := (bits / 8) + (bits % 8) + out := make([]byte, bytes) + for i := 0; i < bytes; i++ { + if bits/8 > 0 { + val, err := reader.ReadBytes(1) + if err != nil { + panic(err) + } + out[i] = byte(val) + } else { // Not enough to fill a whole byte + val, err := reader.ReadBits(bits % 8) + if err != nil { + panic(err) + } + out[i] = byte(val) + } + } + return out +} + // TryReadBytesToSlice is a wrapper function that reads the specified amount of bytes // from the parameter and puts each byte into a slice and returns this slice. func (reader *ReaderType) TryReadBytesToSlice(bytes int) []byte { @@ -289,6 +312,31 @@ func (reader *ReaderType) ReadBytes(bytes int) (uint64, error) { return value, nil } +// ReadBitsToSlice is a function that reads the specified amount of bits +// from the parameter and puts each bit into a slice and returns this slice. +// +// Returns an error if there are no remaining bits. +func (reader *ReaderType) ReadBitsToSlice(bits int) ([]byte, error) { + bytes := (bits / 8) + (bits % 8) + out := make([]byte, bytes) + for i := 0; i < bytes; i++ { + if bits/8 > 0 { + val, err := reader.ReadBytes(1) + if err != nil { + return out, err + } + out[i] = byte(val) + } else { // Not enough to fill a whole byte + val, err := reader.ReadBits(bits % 8) + if err != nil { + panic(err) + } + out[i] = byte(val) + } + } + return out, nil +} + // ReadBytesToSlice is a function that reads the specified amount of bytes // from the parameter and puts each byte into a slice and returns this slice. // -- cgit v1.2.3