This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 7e07c8b94f2fa688ffef09248ac6dd065f43a59c
Author: Sebastian Rühl <[email protected]>
AuthorDate: Mon May 18 16:55:58 2026 +0200

    feat(plc4go): provide builtin bitreader
---
 plc4go/go.mod                                      |  11 +-
 plc4go/go.sum                                      |  24 +-
 .../bacgopes/tests/test_network/test_net_2_test.go |   4 +-
 plc4go/internal/cbus/Reader_test.go                |   4 +-
 plc4go/spi/utils/BitBuffer.go                      | 223 +++++++++++++++
 plc4go/spi/utils/BitBuffer_test.go                 | 309 +++++++++++++++++++++
 plc4go/spi/utils/ReadBufferByteBased.go            | 108 +++----
 plc4go/spi/utils/ReadBufferByteBased_test.go       | 274 +++++++++---------
 plc4go/spi/utils/WriteBufferByteBased.go           |  92 +++---
 plc4go/spi/utils/WriteBufferByteBased_test.go      | 254 ++++++-----------
 10 files changed, 852 insertions(+), 451 deletions(-)

diff --git a/plc4go/go.mod b/plc4go/go.mod
index 21456a9c7f..cf76051e76 100644
--- a/plc4go/go.mod
+++ b/plc4go/go.mod
@@ -28,7 +28,6 @@ require (
        github.com/fatih/color v1.19.0
        github.com/google/uuid v1.6.0
        github.com/gopacket/gopacket v1.5.0
-       github.com/icza/bitio v1.1.0
        github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4
        github.com/libp2p/go-reuseport v0.4.0
        github.com/pkg/errors v0.9.1
@@ -37,9 +36,9 @@ require (
        github.com/stretchr/testify v1.11.1
        github.com/subchen/go-xmldom v1.1.2
        github.com/viney-shih/go-lock v1.1.2
-       golang.org/x/net v0.53.0
+       golang.org/x/net v0.54.0
        golang.org/x/text v0.37.0
-       golang.org/x/tools v0.44.0
+       golang.org/x/tools v0.45.0
 )
 
 require (
@@ -79,10 +78,10 @@ require (
        github.com/xeipuuv/gojsonschema v1.2.0 // indirect
        go.yaml.in/yaml/v3 v3.0.4 // indirect
        golang.org/x/exp v0.0.0-20260211191109-2735e65f0518 // indirect
-       golang.org/x/mod v0.35.0 // indirect
+       golang.org/x/mod v0.36.0 // indirect
        golang.org/x/sync v0.20.0 // indirect
-       golang.org/x/sys v0.43.0 // indirect
-       golang.org/x/term v0.42.0 // indirect
+       golang.org/x/sys v0.44.0 // indirect
+       golang.org/x/term v0.43.0 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect
        gotest.tools/gotestsum v1.13.0 // indirect
 )
diff --git a/plc4go/go.sum b/plc4go/go.sum
index f4b06d6756..882a34104d 100644
--- a/plc4go/go.sum
+++ b/plc4go/go.sum
@@ -37,10 +37,6 @@ github.com/gopacket/gopacket v1.5.0 
h1:9s9fcSUVKFlRV97B77Bq9XNV3ly2gvvsneFMQUGjc
 github.com/gopacket/gopacket v1.5.0/go.mod 
h1:i3NaGaqfoWKAr1+g7qxEdWsmfT+MXuWkAe9+THv8LME=
 github.com/huandu/xstrings v1.5.0 
h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
 github.com/huandu/xstrings v1.5.0/go.mod 
h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/icza/bitio v1.1.0 h1:ysX4vtldjdi3Ygai5m1cWy4oLkhWTAi+SyO6HC8L9T0=
-github.com/icza/bitio v1.1.0/go.mod 
h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A=
-github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 
h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k=
-github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod 
h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA=
 github.com/inconshreveable/mousetrap v1.1.0 
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod 
h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/incu6us/goimports-reviser/v3 v3.11.0 
h1:ApPsIVH/pT1XFwA8ewJR1o6u5y4sqcVZvz4dITCN6Nk=
@@ -125,22 +121,22 @@ go.yaml.in/yaml/v3 v3.0.4 
h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
 go.yaml.in/yaml/v3 v3.0.4/go.mod 
h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
 golang.org/x/exp v0.0.0-20260211191109-2735e65f0518 
h1:2E1CW7v5QB+Wi3N+MXllOtVR6SFmI8iJM8EdzgxrgrU=
 golang.org/x/exp v0.0.0-20260211191109-2735e65f0518/go.mod 
h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
-golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
-golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
-golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
-golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
+golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
+golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
+golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
+golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
 golang.org/x/sync v0.20.0/go.mod 
h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
-golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
-golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
-golang.org/x/term v0.42.0/go.mod 
h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
+golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
+golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
+golang.org/x/term v0.43.0/go.mod 
h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
 golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
 golang.org/x/text v0.37.0/go.mod 
h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
-golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
-golang.org/x/tools v0.44.0/go.mod 
h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
+golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
+golang.org/x/tools v0.45.0/go.mod 
h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c 
h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod 
h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git 
a/plc4go/internal/bacnetip/bacgopes/tests/test_network/test_net_2_test.go 
b/plc4go/internal/bacnetip/bacgopes/tests/test_network/test_net_2_test.go
index 80c693c212..a04aaef9c6 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_network/test_net_2_test.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/test_net_2_test.go
@@ -144,8 +144,8 @@ func (t *TNetwork2) Run(timeLimit time.Duration) {
 
        // check for success
        success, failed := t.CheckForSuccess()
-       assert.True(t.t, success)
-       assert.False(t.t, failed)
+       assert.True(t.t, success, "should have succeeded")
+       assert.False(t.t, failed, "should not have failed")
 }
 
 func TestNet2(t *testing.T) {
diff --git a/plc4go/internal/cbus/Reader_test.go 
b/plc4go/internal/cbus/Reader_test.go
index 1466de5cec..9fb10df2a8 100644
--- a/plc4go/internal/cbus/Reader_test.go
+++ b/plc4go/internal/cbus/Reader_test.go
@@ -334,8 +334,8 @@ func TestReader_readSync(t *testing.T) {
                                        response := result.GetResponse()
                                        assert.NotNil(t, response)
                                        value := response.GetValue("blub")
-                                       assert.NotNil(t, value)
-                                       require.True(t, value.IsString())
+                                       require.NotNil(t, value)
+                                       assert.True(t, value.IsString())
                                        assert.Equal(t, "PC_CNIED", 
value.GetString())
                                }
                                return true
diff --git a/plc4go/spi/utils/BitBuffer.go b/plc4go/spi/utils/BitBuffer.go
new file mode 100644
index 0000000000..918a041dfc
--- /dev/null
+++ b/plc4go/spi/utils/BitBuffer.go
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package utils
+
+import (
+       stdErrors "errors"
+       "io"
+
+       "github.com/pkg/errors"
+)
+
+// ReadBitBuffer reads bits from a fixed byte slice in big-endian bit order.
+// Bit 0 is the MSB of byte 0; bit 7 is the LSB of byte 0; bit 8 is the MSB of 
byte 1, etc.
+type ReadBitBuffer struct {
+       data   []byte
+       bitPos uint64
+}
+
+// NewReadBitBuffer creates a ReadBitBuffer backed by data.
+func NewReadBitBuffer(data []byte) *ReadBitBuffer {
+       return &ReadBitBuffer{data: data}
+}
+
+// ResetTo repositions the read cursor to the given bit offset.
+func (b *ReadBitBuffer) ResetTo(bitPos uint64) {
+       b.bitPos = bitPos
+}
+
+// BitsRemaining returns the number of bits that can still be read.
+func (b *ReadBitBuffer) BitsRemaining() uint64 {
+       total := uint64(len(b.data)) * 8
+       if b.bitPos >= total {
+               return 0
+       }
+       return total - b.bitPos
+}
+
+// ReadBool reads 1 bit.
+func (b *ReadBitBuffer) ReadBool() (bool, error) {
+       v, err := b.ReadBits(1)
+       return v != 0, err
+}
+
+// ReadByte reads 8 bits as a byte.
+func (b *ReadBitBuffer) ReadByte() (byte, error) {
+       v, err := b.ReadBits(8)
+       return byte(v), err
+}
+
+// Read reads len(p) bytes, implementing io.Reader.
+func (b *ReadBitBuffer) Read(p []byte) (int, error) {
+       for i := range p {
+               v, err := b.ReadBits(8)
+               if err != nil {
+                       return i, err
+               }
+               p[i] = byte(v)
+       }
+       return len(p), nil
+}
+
+// ReadBits reads n bits (0 ≤ n ≤ 64) in big-endian order, returning them 
right-aligned in a uint64.
+func (b *ReadBitBuffer) ReadBits(n uint8) (uint64, error) {
+       if n == 0 {
+               return 0, nil
+       }
+       if n > 64 {
+               return 0, errors.New("cannot read more than 64 bits at once")
+       }
+       if uint64(n) > b.BitsRemaining() {
+               return 0, io.ErrUnexpectedEOF
+       }
+
+       var result uint64
+       bitsLeft := n
+
+       // Partial first byte when the cursor is not byte-aligned
+       if bitOffset := b.bitPos % 8; bitOffset != 0 {
+               bitsAvail := uint8(8 - bitOffset)
+               bitsToRead := bitsAvail
+               if bitsToRead > bitsLeft {
+                       bitsToRead = bitsLeft
+               }
+               byteVal := b.data[b.bitPos/8]
+               shift := bitsAvail - bitsToRead
+               mask := uint8((1 << bitsToRead) - 1)
+               result = uint64((byteVal >> shift) & mask)
+               b.bitPos += uint64(bitsToRead)
+               bitsLeft -= bitsToRead
+       }
+
+       // Full bytes
+       for bitsLeft >= 8 {
+               result = (result << 8) | uint64(b.data[b.bitPos/8])
+               b.bitPos += 8
+               bitsLeft -= 8
+       }
+
+       // Partial last byte
+       if bitsLeft > 0 {
+               byteVal := b.data[b.bitPos/8]
+               result = (result << bitsLeft) | uint64(byteVal>>(8-bitsLeft))
+               b.bitPos += uint64(bitsLeft)
+       }
+
+       return result, nil
+}
+
+// WriteBitBuffer accumulates bits in big-endian order into an internal byte 
slice.
+// Bits are placed MSB-first within each byte.
+type WriteBitBuffer struct {
+       buf         []byte
+       pending     byte  // partial byte being assembled from the MSB side
+       pendingBits uint8 // number of bits used in pending (0–7)
+       tryError    error // accumulated error from TryWrite methods
+}
+
+// NewWriteBitBuffer creates a WriteBitBuffer with the given initial capacity 
hint.
+func NewWriteBitBuffer(initialCap int) *WriteBitBuffer {
+       return &WriteBitBuffer{buf: make([]byte, 0, initialCap)}
+}
+
+// WriteBool writes a single bit.
+func (w *WriteBitBuffer) WriteBool(v bool) error {
+       var bit uint64
+       if v {
+               bit = 1
+       }
+       return w.WriteBits(bit, 1)
+}
+
+// WriteBits writes n bits (0 ≤ n ≤ 64) from the LSBs of val, MSB first.
+func (w *WriteBitBuffer) WriteBits(val uint64, n uint8) error {
+       if n == 0 {
+               return nil
+       }
+       if n > 64 {
+               return errors.New("cannot write more than 64 bits at once")
+       }
+
+       bitsLeft := n
+
+       // Fill the in-progress pending byte first
+       if w.pendingBits > 0 {
+               bitsToWrite := uint8(8 - w.pendingBits)
+               if bitsToWrite > bitsLeft {
+                       bitsToWrite = bitsLeft
+               }
+               shift := bitsLeft - bitsToWrite
+               bits := uint8((val >> shift) & ((1 << bitsToWrite) - 1))
+               w.pending |= bits << (8 - w.pendingBits - bitsToWrite)
+               w.pendingBits += bitsToWrite
+               bitsLeft -= bitsToWrite
+               if w.pendingBits == 8 {
+                       w.buf = append(w.buf, w.pending)
+                       w.pending = 0
+                       w.pendingBits = 0
+               }
+       }
+
+       // Write full bytes directly
+       for bitsLeft >= 8 {
+               bitsLeft -= 8
+               w.buf = append(w.buf, byte(val>>bitsLeft))
+       }
+
+       // Store remaining bits in pending
+       if bitsLeft > 0 {
+               w.pending = uint8(val&((1<<bitsLeft)-1)) << (8 - bitsLeft)
+               w.pendingBits = bitsLeft
+       }
+
+       return nil
+}
+
+// TryWriteByte writes a byte, accumulating any error into GetTryError.
+func (w *WriteBitBuffer) TryWriteByte(b byte) {
+       if err := w.WriteBits(uint64(b), 8); err != nil && w.tryError == nil {
+               w.tryError = stdErrors.Join(w.tryError, err)
+       }
+}
+
+// GetTryError returns the accumulated error from TryWriteByte calls.
+func (w *WriteBitBuffer) GetTryError() error {
+       return w.tryError
+}
+
+// flush pads the pending partial byte with zero bits and appends it.
+func (w *WriteBitBuffer) flush() {
+       if w.pendingBits > 0 {
+               w.buf = append(w.buf, w.pending)
+               w.pending = 0
+               w.pendingBits = 0
+       }
+}
+
+// Bytes flushes any pending partial byte (zero-padded) and returns all 
written bytes.
+func (w *WriteBitBuffer) Bytes() []byte {
+       w.flush()
+       return w.buf
+}
+
+// ByteLen returns the number of complete bytes written, excluding any pending 
partial byte.
+func (w *WriteBitBuffer) ByteLen() int {
+       return len(w.buf)
+}
diff --git a/plc4go/spi/utils/BitBuffer_test.go 
b/plc4go/spi/utils/BitBuffer_test.go
new file mode 100644
index 0000000000..9b79f6bfed
--- /dev/null
+++ b/plc4go/spi/utils/BitBuffer_test.go
@@ -0,0 +1,309 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package utils
+
+import (
+       "io"
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+// ── ReadBitBuffer ──────────────────────────────────────────────────────────
+
+func TestReadBitBuffer_BitsRemaining(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xFF, 0x00})
+       assert.Equal(t, uint64(16), b.BitsRemaining())
+
+       _, _ = b.ReadBits(4)
+       assert.Equal(t, uint64(12), b.BitsRemaining())
+
+       _, _ = b.ReadBits(12)
+       assert.Equal(t, uint64(0), b.BitsRemaining())
+}
+
+func TestReadBitBuffer_ReadBits_ByteAligned(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xAB, 0xCD})
+
+       v, err := b.ReadBits(8)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xAB), v)
+
+       v, err = b.ReadBits(8)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xCD), v)
+}
+
+func TestReadBitBuffer_ReadBits_CrossByte(t *testing.T) {
+       // 0xAB = 1010_1011, 0xCD = 1100_1101
+       // Reading 4 bits then 8 bits: first 4 = 0xA (1010), next 8 cross the 
byte boundary
+       // bits 4-11: 1011_1100 = 0xBC
+       b := NewReadBitBuffer([]byte{0xAB, 0xCD})
+
+       v, err := b.ReadBits(4)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xA), v)
+
+       v, err = b.ReadBits(8)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xBC), v)
+}
+
+func TestReadBitBuffer_ReadBits_Partial(t *testing.T) {
+       // 0b10110000 — read top 3 bits = 0b101 = 5
+       b := NewReadBitBuffer([]byte{0b10110000})
+
+       v, err := b.ReadBits(3)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(5), v)
+}
+
+func TestReadBitBuffer_ReadBool(t *testing.T) {
+       // 0b10000000: first bit = 1 (true), second bit = 0 (false)
+       b := NewReadBitBuffer([]byte{0b10000000})
+
+       v, err := b.ReadBool()
+       require.NoError(t, err)
+       assert.True(t, v)
+
+       v, err = b.ReadBool()
+       require.NoError(t, err)
+       assert.False(t, v)
+}
+
+func TestReadBitBuffer_ReadByte(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xDE, 0xAD})
+
+       byt, err := b.ReadByte()
+       require.NoError(t, err)
+       assert.Equal(t, byte(0xDE), byt)
+}
+
+func TestReadBitBuffer_Read(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0x01, 0x02, 0x03})
+       p := make([]byte, 3)
+       n, err := b.Read(p)
+       require.NoError(t, err)
+       assert.Equal(t, 3, n)
+       assert.Equal(t, []byte{0x01, 0x02, 0x03}, p)
+}
+
+func TestReadBitBuffer_ReadBits_EOF(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xFF})
+       _, err := b.ReadBits(9)
+       assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
+}
+
+func TestReadBitBuffer_ReadBits_Zero(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xFF})
+       v, err := b.ReadBits(0)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0), v)
+}
+
+func TestReadBitBuffer_ReadBits_TooMany(t *testing.T) {
+       b := NewReadBitBuffer(make([]byte, 9))
+       _, err := b.ReadBits(65)
+       require.Error(t, err)
+       assert.Equal(t, uint64(72), b.BitsRemaining(), "cursor must not advance 
on error")
+}
+
+func TestReadBitBuffer_ReadBits_64(t *testing.T) {
+       data := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
+       b := NewReadBitBuffer(data)
+       v, err := b.ReadBits(64)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0x0102030405060708), v)
+       assert.Equal(t, uint64(0), b.BitsRemaining())
+}
+
+func TestReadBitBuffer_EmptyBuffer(t *testing.T) {
+       b := NewReadBitBuffer([]byte{})
+       assert.Equal(t, uint64(0), b.BitsRemaining())
+       _, err := b.ReadBits(1)
+       assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
+}
+
+func TestReadBitBuffer_Read_Partial(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xAA})
+       p := make([]byte, 3)
+       n, err := b.Read(p)
+       assert.Equal(t, 1, n)
+       assert.Error(t, err)
+       assert.Equal(t, byte(0xAA), p[0])
+}
+
+func TestReadBitBuffer_ResetTo(t *testing.T) {
+       b := NewReadBitBuffer([]byte{0xAB, 0xCD})
+
+       v, err := b.ReadBits(8)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xAB), v)
+
+       b.ResetTo(0)
+       v, err = b.ReadBits(8)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xAB), v)
+}
+
+func TestReadBitBuffer_ResetTo_NonZero(t *testing.T) {
+       // Reset to bit position 4 (mid-byte) and read the lower nibble of 0xAB.
+       // 0xAB = 1010_1011 → lower 4 bits = 0xB
+       b := NewReadBitBuffer([]byte{0xAB, 0xCD})
+       b.ResetTo(4)
+       v, err := b.ReadBits(4)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xB), v)
+}
+
+// ── WriteBitBuffer ─────────────────────────────────────────────────────────
+
+func TestWriteBitBuffer_WriteByteAligned(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0xAB, 8))
+       require.NoError(t, w.WriteBits(0xCD, 8))
+       assert.Equal(t, []byte{0xAB, 0xCD}, w.Bytes())
+}
+
+func TestWriteBitBuffer_WriteBool(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBool(true))
+       require.NoError(t, w.WriteBool(false))
+       require.NoError(t, w.WriteBool(true))
+       require.NoError(t, w.WriteBool(true))
+       require.NoError(t, w.WriteBool(false))
+       require.NoError(t, w.WriteBool(false))
+       require.NoError(t, w.WriteBool(false))
+       require.NoError(t, w.WriteBool(false))
+       // 1011_0000 = 0xB0
+       assert.Equal(t, []byte{0xB0}, w.Bytes())
+}
+
+func TestWriteBitBuffer_WritePartialThenAlign(t *testing.T) {
+       // Write 4 bits of 0xA (1010), then 4 bits of 0xB (1011) → 0xAB
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0xA, 4))
+       require.NoError(t, w.WriteBits(0xB, 4))
+       assert.Equal(t, []byte{0xAB}, w.Bytes())
+}
+
+func TestWriteBitBuffer_WriteCrossByte(t *testing.T) {
+       // Write 4 bits 0xA, then 8 bits 0xBC, then 4 bits 0xD
+       // Result bytes: 0xA<<4 | 0xB = 0xAB, 0xC<<4 | 0xD = 0xCD
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0xA, 4))
+       require.NoError(t, w.WriteBits(0xBC, 8))
+       require.NoError(t, w.WriteBits(0xD, 4))
+       assert.Equal(t, []byte{0xAB, 0xCD}, w.Bytes())
+}
+
+func TestWriteBitBuffer_PendingFlushedWithZeroPad(t *testing.T) {
+       // Write 3 bits: 0b101 → should be padded to 0b10100000 = 0xA0
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0b101, 3))
+       assert.Equal(t, []byte{0xA0}, w.Bytes())
+}
+
+func TestWriteBitBuffer_ByteLen(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0xAB, 8))
+       require.NoError(t, w.WriteBits(0b101, 3)) // pending, not yet flushed
+       assert.Equal(t, 1, w.ByteLen())           // only the complete byte
+}
+
+func TestWriteBitBuffer_TryWriteByte(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       w.TryWriteByte(0xDE)
+       w.TryWriteByte(0xAD)
+       assert.NoError(t, w.GetTryError())
+       assert.Equal(t, []byte{0xDE, 0xAD}, w.Bytes())
+}
+
+func TestWriteBitBuffer_WriteBits_Zero(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0xFF, 0))
+       assert.Equal(t, []byte{}, w.Bytes())
+}
+
+func TestWriteBitBuffer_WriteBits_TooMany(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       err := w.WriteBits(0, 65)
+       require.Error(t, err)
+       assert.Equal(t, []byte{}, w.Bytes(), "buffer must not change on error")
+}
+
+func TestWriteBitBuffer_WriteBits_64(t *testing.T) {
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0x0102030405060708, 64))
+       assert.Equal(t, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 
w.Bytes())
+}
+
+func TestWriteBitBuffer_SmallWriteIntoPartialPending(t *testing.T) {
+       // Write 3 bits (1=101), then 2 bits (1=11) — neither fills the pending 
byte.
+       // After both: pending = 101_11_000 → but pending only holds one byte 
(8 bits),
+       // so 5 bits used: 1011_1000 wait — it's MSB first:
+       // bit 7: 1, bit 6: 0, bit 5: 1 → after first write, pending=1010_0000
+       // then write 11: bit 4: 1, bit 3: 1 → pending=1011_1000 = 0xB8
+       // Then flush via Bytes()
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0b101, 3))
+       require.NoError(t, w.WriteBits(0b11, 2))
+       assert.Equal(t, 0, w.ByteLen(), "no complete bytes yet")
+       assert.Equal(t, []byte{0b10111000}, w.Bytes()) // 101_11_000 
zero-padded = 0xB8
+}
+
+func TestWriteBitBuffer_HighBitsInValIgnored(t *testing.T) {
+       // Only the lower n bits of val should be written.
+       // WriteBits(0xFF, 4) should write 0b1111, not the upper 4 bits.
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(0xFF, 4))
+       require.NoError(t, w.WriteBits(0x00, 4))
+       assert.Equal(t, []byte{0xF0}, w.Bytes())
+}
+
+// ── Round-trip ─────────────────────────────────────────────────────────────
+
+func TestBitBuffer_RoundTrip(t *testing.T) {
+       // Write a sequence of non-byte-aligned fields and read them back.
+       w := NewWriteBitBuffer(0)
+       require.NoError(t, w.WriteBits(1, 1))       // 1 bit
+       require.NoError(t, w.WriteBits(0xA, 4))     // 4 bits
+       require.NoError(t, w.WriteBits(0x1F, 5))    // 5 bits
+       require.NoError(t, w.WriteBits(0xABCD, 16)) // 16 bits (2 full bytes)
+
+       r := NewReadBitBuffer(w.Bytes())
+
+       v, err := r.ReadBits(1)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(1), v)
+
+       v, err = r.ReadBits(4)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xA), v)
+
+       v, err = r.ReadBits(5)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0x1F), v)
+
+       v, err = r.ReadBits(16)
+       require.NoError(t, err)
+       assert.Equal(t, uint64(0xABCD), v)
+}
diff --git a/plc4go/spi/utils/ReadBufferByteBased.go 
b/plc4go/spi/utils/ReadBufferByteBased.go
index b83c87eb8a..db4755c5f7 100644
--- a/plc4go/spi/utils/ReadBufferByteBased.go
+++ b/plc4go/spi/utils/ReadBufferByteBased.go
@@ -20,12 +20,10 @@
 package utils
 
 import (
-       "bytes"
        "encoding/binary"
        "math"
        "math/big"
 
-       "github.com/icza/bitio"
        "github.com/pkg/errors"
 )
 
@@ -37,11 +35,9 @@ type ReadBufferByteBased interface {
 }
 
 func NewReadBufferByteBased(data []byte, options 
...ReadBufferByteBasedOptions) ReadBufferByteBased {
-       buffer := bytes.NewBuffer(data)
-       reader := bitio.NewReader(buffer)
        b := &byteReadBuffer{
                data:      data,
-               reader:    reader,
+               bits:      NewReadBitBuffer(data),
                pos:       uint64(0),
                byteOrder: binary.BigEndian,
        }
@@ -67,7 +63,7 @@ func WithByteOrderForReadBufferByteBased(byteOrder 
binary.ByteOrder) ReadBufferB
 
 type byteReadBuffer struct {
        data      []byte
-       reader    *bitio.Reader
+       bits      *ReadBitBuffer
        pos       uint64
        byteOrder binary.ByteOrder
 }
@@ -93,14 +89,8 @@ func (rb *byteReadBuffer) GetPos() uint16 {
 }
 
 func (rb *byteReadBuffer) Reset(pos uint16) {
-       rb.pos = uint64(0)
-       rb.reader = bitio.NewReader(bytes.NewBuffer(rb.data))
-       bytesToSkip := make([]byte, pos)
-       _, err := rb.reader.Read(bytesToSkip)
-       if err != nil {
-               panic(errors.Wrap(err, "Should not happen")) // TODO: maybe 
this is a possible occurence since we accept a argument, better returns a error
-       }
-       rb.pos = uint64(pos * 8)
+       rb.pos = uint64(pos) * 8
+       rb.bits.ResetTo(rb.pos)
 }
 
 func (rb *byteReadBuffer) GetBytes() []byte {
@@ -125,19 +115,19 @@ func (rb *byteReadBuffer) PullContext(_ string, _ 
...WithReaderArgs) error {
 
 func (rb *byteReadBuffer) ReadBit(_ string, _ ...WithReaderArgs) (bool, error) 
{
        rb.pos += 1
-       return rb.reader.ReadBool()
+       return rb.bits.ReadBool()
 }
 
 func (rb *byteReadBuffer) ReadByte(_ string, _ ...WithReaderArgs) (byte, 
error) {
        rb.pos += 8
-       return rb.reader.ReadByte()
+       return rb.bits.ReadByte()
 }
 
 func (rb *byteReadBuffer) ReadByteArray(_ string, numberOfBytes int, _ 
...WithReaderArgs) ([]byte, error) {
        byteArray := make([]byte, numberOfBytes)
        for i := range numberOfBytes {
                rb.pos += 8
-               readByte, err := rb.reader.ReadByte()
+               readByte, err := rb.bits.ReadByte()
                if err != nil {
                        return nil, err
                }
@@ -147,7 +137,7 @@ func (rb *byteReadBuffer) ReadByteArray(_ string, 
numberOfBytes int, _ ...WithRe
 }
 
 func (rb *byteReadBuffer) ReadUint8(_ string, bitLength uint8, _ 
...WithReaderArgs) (uint8, error) {
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -164,7 +154,7 @@ func (rb *byteReadBuffer) ReadUint16(logicalName string, 
bitLength uint8, _ ...W
                }
                return uint16(bigInt.Uint64()), nil
        }
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -181,7 +171,7 @@ func (rb *byteReadBuffer) ReadUint32(logicalName string, 
bitLength uint8, _ ...W
                }
                return uint32(bigInt.Uint64()), nil
        }
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -198,7 +188,7 @@ func (rb *byteReadBuffer) ReadUint64(logicalName string, 
bitLength uint8, _ ...W
                }
                return bigInt.Uint64(), nil
        }
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -207,7 +197,7 @@ func (rb *byteReadBuffer) ReadUint64(logicalName string, 
bitLength uint8, _ ...W
 }
 
 func (rb *byteReadBuffer) ReadInt8(_ string, bitLength uint8, _ 
...WithReaderArgs) (int8, error) {
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -224,7 +214,7 @@ func (rb *byteReadBuffer) ReadInt16(logicalName string, 
bitLength uint8, _ ...Wi
                }
                return int16(bigInt.Int64()), nil
        }
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -241,7 +231,7 @@ func (rb *byteReadBuffer) ReadInt32(logicalName string, 
bitLength uint8, _ ...Wi
                }
                return int32(bigInt.Int64()), nil
        }
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -258,7 +248,7 @@ func (rb *byteReadBuffer) ReadInt64(logicalName string, 
bitLength uint8, _ ...Wi
                }
                return bigInt.Int64(), nil
        }
-       res, err := rb.reader.ReadBits(bitLength)
+       res, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
@@ -267,52 +257,37 @@ func (rb *byteReadBuffer) ReadInt64(logicalName string, 
bitLength uint8, _ ...Wi
 }
 
 func (rb *byteReadBuffer) ReadBigInt(_ string, bitLength uint64, _ 
...WithReaderArgs) (*big.Int, error) {
-       // TODO: highly experimental remove this comment when tested or verifyed
-       res := big.NewInt(0)
-
-       // TODO: maybe we can use left shift and or of big int
-       rawBytes := make([]byte, 0)
-       correction := uint8(0)
-
-       for remainingBits := bitLength; remainingBits > 0; {
-               // we can max read 64 bit with bitio
-               bitToRead := uint8(64)
-               if remainingBits < 64 {
-                       bitToRead = uint8(remainingBits)
+       // TODO: highly experimental remove this comment when tested or verified
+       rawBytes := make([]byte, 0, (bitLength+7)/8)
+
+       fullBytes := bitLength / 8
+       remainingBits := uint8(bitLength % 8)
+
+       for range fullBytes {
+               b, err := rb.bits.ReadByte()
+               if err != nil {
+                       return nil, errors.Wrapf(err, "error reading big int at 
pos [%d]bit ([%d]byte)", rb.pos, rb.pos/8)
                }
-               // we now read the bits
-               data, err := rb.reader.ReadBits(bitToRead)
+               rb.pos += 8
+               rawBytes = append(rawBytes, b)
+       }
+       if remainingBits > 0 {
+               b, err := rb.bits.ReadBits(remainingBits)
                if err != nil {
-                       return nil, errors.Wrapf(err, "error reading %d bits at 
pos [%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
+                       return nil, errors.Wrapf(err, "error reading big int at 
pos [%d]bit ([%d]byte)", rb.pos, rb.pos/8)
                }
-               rb.pos += bitLength
-
-               // and check for uneven bits for a right shift at the end
-               correction = 64 - bitToRead
-               data <<= correction
-
-               dataBytes := make([]byte, 8)
-               binary.BigEndian.PutUint64(dataBytes, data)
-               rawBytes = append(rawBytes, dataBytes...)
-
-               remainingBits -= uint64(bitToRead)
+               rb.pos += uint64(remainingBits)
+               rawBytes = append(rawBytes, byte(b))
        }
 
-       res.SetBytes(rawBytes)
+       res := new(big.Int).SetBytes(rawBytes)
 
-       // now we need to shift the last correction to right again
-       res.Rsh(res, uint(correction))
        if rb.byteOrder == binary.LittleEndian {
-               originalByteLength := len(rawBytes) - int(correction/8)
-               resBytes := res.Bytes()
-               padding := make([]byte, originalByteLength-len(resBytes))
-               resBytes = append(padding, resBytes...)
-               if rb.byteOrder == binary.LittleEndian {
-                       for i, j := 0, len(resBytes)-1; i <= j; i, j = i+1, j-1 
{
-                               resBytes[i], resBytes[j] = resBytes[j], 
resBytes[i]
-                       }
+               // rawBytes are in LE stream order; reverse to get BE for 
big.Int
+               for i, j := 0, len(rawBytes)-1; i < j; i, j = i+1, j-1 {
+                       rawBytes[i], rawBytes[j] = rawBytes[j], rawBytes[i]
                }
-               res.SetBytes(resBytes)
+               res.SetBytes(rawBytes)
        }
 
        return res, nil
@@ -320,13 +295,12 @@ func (rb *byteReadBuffer) ReadBigInt(_ string, bitLength 
uint64, _ ...WithReader
 
 func (rb *byteReadBuffer) ReadFloat32(logicalName string, bitLength uint8, _ 
...WithReaderArgs) (float32, error) {
        if bitLength == 32 {
-               var uintValue uint32
-               _uintValue, err := rb.reader.ReadBits(bitLength)
+               _uintValue, err := rb.bits.ReadBits(bitLength)
                if err != nil {
                        return 0, errors.Wrapf(err, "error reading %d bits at 
pos [%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
                }
                rb.pos += uint64(bitLength)
-               uintValue = uint32(_uintValue)
+               uintValue := uint32(_uintValue)
                if rb.byteOrder == binary.LittleEndian {
                        array := make([]byte, 4)
                        binary.LittleEndian.PutUint32(array, uintValue)
@@ -357,7 +331,7 @@ func (rb *byteReadBuffer) ReadFloat32(logicalName string, 
bitLength uint8, _ ...
 }
 
 func (rb *byteReadBuffer) ReadFloat64(_ string, bitLength uint8, _ 
...WithReaderArgs) (float64, error) {
-       uintValue, err := rb.reader.ReadBits(bitLength)
+       uintValue, err := rb.bits.ReadBits(bitLength)
        if err != nil {
                return 0, errors.Wrapf(err, "error reading %d bits at pos 
[%d]bit ([%d]byte)", bitLength, rb.pos, rb.pos/8)
        }
diff --git a/plc4go/spi/utils/ReadBufferByteBased_test.go 
b/plc4go/spi/utils/ReadBufferByteBased_test.go
index 99e0d75dfd..b875a26e7a 100644
--- a/plc4go/spi/utils/ReadBufferByteBased_test.go
+++ b/plc4go/spi/utils/ReadBufferByteBased_test.go
@@ -20,14 +20,12 @@
 package utils
 
 import (
-       "bytes"
        "encoding/binary"
        "fmt"
        "math"
        "math/big"
        "testing"
 
-       "github.com/icza/bitio"
        "github.com/stretchr/testify/assert"
 )
 
@@ -43,7 +41,7 @@ func TestNewReadBuffer(t *testing.T) {
                {
                        name: "create it",
                        want: &byteReadBuffer{
-                               reader:    
bitio.NewReader(bytes.NewBuffer(nil)),
+                               bits:      &ReadBitBuffer{},
                                byteOrder: binary.BigEndian,
                        },
                },
@@ -60,7 +58,7 @@ func TestNewReadBuffer(t *testing.T) {
 func TestReadBuffer_GetBytes(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -77,7 +75,7 @@ func TestReadBuffer_GetBytes(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -91,7 +89,7 @@ func TestReadBuffer_GetBytes(t *testing.T) {
 func TestReadBuffer_GetPos(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -108,7 +106,7 @@ func TestReadBuffer_GetPos(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -122,7 +120,7 @@ func TestReadBuffer_GetPos(t *testing.T) {
 func TestReadBuffer_GetTotalBytes(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -139,7 +137,7 @@ func TestReadBuffer_GetTotalBytes(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -153,7 +151,7 @@ func TestReadBuffer_GetTotalBytes(t *testing.T) {
 func TestReadBuffer_HasMore(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -175,7 +173,7 @@ func TestReadBuffer_HasMore(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -189,7 +187,7 @@ func TestReadBuffer_HasMore(t *testing.T) {
 func TestReadBuffer_PeekByte(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -213,7 +211,7 @@ func TestReadBuffer_PeekByte(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -227,7 +225,7 @@ func TestReadBuffer_PeekByte(t *testing.T) {
 func TestReadBuffer_ReadBigFloat(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -244,7 +242,7 @@ func TestReadBuffer_ReadBigFloat(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: bitio.NewReader(bytes.NewBuffer(nil)),
+                               bits: &ReadBitBuffer{},
                        },
                        want: big.NewFloat(0),
                },
@@ -253,7 +251,7 @@ func TestReadBuffer_ReadBigFloat(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -272,7 +270,7 @@ func TestReadBuffer_ReadBigFloat(t *testing.T) {
 func TestReadBuffer_ReadBigInt(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -289,7 +287,7 @@ func TestReadBuffer_ReadBigInt(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: bitio.NewReader(bytes.NewBuffer(nil)),
+                               bits: &ReadBitBuffer{},
                        },
                        want: big.NewInt(0),
                },
@@ -298,7 +296,7 @@ func TestReadBuffer_ReadBigInt(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -317,7 +315,7 @@ func TestReadBuffer_ReadBigInt(t *testing.T) {
 func TestReadBuffer_ReadBit(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -330,7 +328,7 @@ func TestReadBuffer_ReadBit(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
        }
@@ -338,7 +336,7 @@ func TestReadBuffer_ReadBit(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -357,7 +355,7 @@ func TestReadBuffer_ReadBit(t *testing.T) {
 func TestReadBuffer_ReadFloat32(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -374,7 +372,7 @@ func TestReadBuffer_ReadFloat32(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
@@ -383,7 +381,7 @@ func TestReadBuffer_ReadFloat32(t *testing.T) {
                                bitLength: 32,
                        },
                        fields: fields{
-                               reader:    
bitio.NewReader(bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x0})),
+                               bits:      NewReadBitBuffer([]byte{0x0, 0x0, 
0x0, 0x0}),
                                byteOrder: binary.LittleEndian,
                        },
                },
@@ -399,7 +397,7 @@ func TestReadBuffer_ReadFloat32(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -418,7 +416,7 @@ func TestReadBuffer_ReadFloat32(t *testing.T) {
 func TestReadBuffer_ReadFloat64(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -448,7 +446,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased(rawData)
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -467,7 +465,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased(rawData, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -486,7 +484,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased(rawData)
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -505,7 +503,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased(rawData, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -522,7 +520,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x3F, 
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -539,7 +537,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x02, 
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -556,7 +554,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -573,7 +571,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -590,7 +588,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0xC0, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -607,7 +605,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -633,7 +631,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -650,7 +648,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -667,7 +665,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -684,7 +682,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -701,7 +699,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -718,7 +716,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -735,7 +733,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -752,7 +750,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -769,7 +767,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -786,7 +784,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -803,7 +801,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x3F, 
0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -820,7 +818,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x3F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -844,7 +842,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -861,7 +859,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x01, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -878,7 +876,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -895,7 +893,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0xFF, 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -912,7 +910,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -929,7 +927,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -946,7 +944,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x7F, 
0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -963,7 +961,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0xFF, 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -991,7 +989,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1008,7 +1006,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1025,7 +1023,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x80, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1042,7 +1040,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1059,7 +1057,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x7F, 
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1076,7 +1074,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1093,7 +1091,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0xFF, 
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1110,7 +1108,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x00, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1127,7 +1125,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x7F, 
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1144,7 +1142,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x01, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1161,7 +1159,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x7F, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1178,7 +1176,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x01, 
0xF8, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1195,7 +1193,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x7F, 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1212,7 +1210,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0xFF, 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1232,7 +1230,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x3F, 
0xD5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x16})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1249,7 +1247,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x16, 
0x55, 0x55, 0x55, 0x55, 0x55, 0xD5, 0x3F}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1270,7 +1268,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x40, 
0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1287,7 +1285,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                                buffer := NewReadBufferByteBased([]byte{0x18, 
0x2D, 0x44, 0x54, 0xFB, 0x21, 0x09, 0x40}, 
WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1303,7 +1301,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1323,7 +1321,7 @@ func TestReadBuffer_ReadFloat64(t *testing.T) {
 func TestReadBuffer_ReadInt16(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1340,13 +1338,13 @@ func TestReadBuffer_ReadInt16(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
                        name: "read it LE",
                        fields: fields{
-                               reader:    
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits:      NewReadBitBuffer([]byte{0x0}),
                                byteOrder: binary.LittleEndian,
                        },
                },
@@ -1355,7 +1353,7 @@ func TestReadBuffer_ReadInt16(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1374,7 +1372,7 @@ func TestReadBuffer_ReadInt16(t *testing.T) {
 func TestReadBuffer_ReadInt32(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1391,13 +1389,13 @@ func TestReadBuffer_ReadInt32(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
                        name: "read it LE",
                        fields: fields{
-                               reader:    
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits:      NewReadBitBuffer([]byte{0x0}),
                                byteOrder: binary.LittleEndian,
                        },
                },
@@ -1406,7 +1404,7 @@ func TestReadBuffer_ReadInt32(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1425,7 +1423,7 @@ func TestReadBuffer_ReadInt32(t *testing.T) {
 func TestReadBuffer_ReadInt64(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1442,13 +1440,13 @@ func TestReadBuffer_ReadInt64(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
                        name: "read it LE",
                        fields: fields{
-                               reader:    
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits:      NewReadBitBuffer([]byte{0x0}),
                                byteOrder: binary.LittleEndian,
                        },
                },
@@ -1457,7 +1455,7 @@ func TestReadBuffer_ReadInt64(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1476,7 +1474,7 @@ func TestReadBuffer_ReadInt64(t *testing.T) {
 func TestReadBuffer_ReadInt8(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1493,7 +1491,7 @@ func TestReadBuffer_ReadInt8(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
        }
@@ -1501,7 +1499,7 @@ func TestReadBuffer_ReadInt8(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1520,7 +1518,7 @@ func TestReadBuffer_ReadInt8(t *testing.T) {
 func TestReadBuffer_ReadString(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1538,14 +1536,14 @@ func TestReadBuffer_ReadString(t *testing.T) {
                        name: "read it",
                        args: args{bitLength: 8},
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
                        name: "read it (null terminated)",
                        args: args{bitLength: 8},
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x70, 0x0})),
+                               bits: NewReadBitBuffer([]byte{0x70, 0x0}),
                        },
                        want: "p",
                },
@@ -1553,7 +1551,7 @@ func TestReadBuffer_ReadString(t *testing.T) {
                        name: "read it",
                        args: args{bitLength: 8},
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x70})),
+                               bits: NewReadBitBuffer([]byte{0x70}),
                        },
                        want: "p",
                },
@@ -1562,7 +1560,7 @@ func TestReadBuffer_ReadString(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1581,7 +1579,7 @@ func TestReadBuffer_ReadString(t *testing.T) {
 func TestReadBuffer_ReadUint16(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1598,13 +1596,13 @@ func TestReadBuffer_ReadUint16(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
                        name: "read it LE",
                        fields: fields{
-                               reader:    
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits:      NewReadBitBuffer([]byte{0x0}),
                                byteOrder: binary.LittleEndian,
                        },
                },
@@ -1613,7 +1611,7 @@ func TestReadBuffer_ReadUint16(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1632,7 +1630,7 @@ func TestReadBuffer_ReadUint16(t *testing.T) {
 func TestReadBuffer_ReadUint32(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1652,7 +1650,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x0, 0x0, 0x1})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1667,7 +1665,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x0, 0x0, 0x10})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1682,7 +1680,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x0, 0x1, 0x0})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1697,7 +1695,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x1, 0x0, 0x0})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1712,7 +1710,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x1, 
0x0, 0x0, 0x0})
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1727,7 +1725,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x1, 
0x0, 0x0, 0x0}, WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1742,7 +1740,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x10, 
0x0, 0x0, 0x0}, WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1757,7 +1755,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x1, 0x0, 0x0}, WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1772,7 +1770,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x0, 0x1, 0x0}, WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1787,7 +1785,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                                buffer := NewReadBufferByteBased([]uint8{0x0, 
0x0, 0x0, 0x1}, WithByteOrderForReadBufferByteBased(binary.LittleEndian))
                                return fields{
                                        data:      
buffer.(*byteReadBuffer).data,
-                                       reader:    
buffer.(*byteReadBuffer).reader,
+                                       bits:      
buffer.(*byteReadBuffer).bits,
                                        pos:       buffer.(*byteReadBuffer).pos,
                                        byteOrder: 
buffer.(*byteReadBuffer).byteOrder,
                                }
@@ -1801,7 +1799,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1820,7 +1818,7 @@ func TestReadBuffer_ReadUint32(t *testing.T) {
 func TestReadBuffer_ReadUint64(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1837,13 +1835,13 @@ func TestReadBuffer_ReadUint64(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
                {
                        name: "read it LE",
                        fields: fields{
-                               reader:    
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits:      NewReadBitBuffer([]byte{0x0}),
                                byteOrder: binary.LittleEndian,
                        },
                },
@@ -1852,7 +1850,7 @@ func TestReadBuffer_ReadUint64(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1871,7 +1869,7 @@ func TestReadBuffer_ReadUint64(t *testing.T) {
 func TestReadBuffer_ReadUint8(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1888,7 +1886,7 @@ func TestReadBuffer_ReadUint8(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
        }
@@ -1896,7 +1894,7 @@ func TestReadBuffer_ReadUint8(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1915,7 +1913,7 @@ func TestReadBuffer_ReadUint8(t *testing.T) {
 func TestReadBuffer_Reset(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1930,7 +1928,7 @@ func TestReadBuffer_Reset(t *testing.T) {
                {
                        name: "reset it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
        }
@@ -1938,7 +1936,7 @@ func TestReadBuffer_Reset(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1950,7 +1948,7 @@ func TestReadBuffer_Reset(t *testing.T) {
 func TestReadBuffer_SetByteOrder(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1965,7 +1963,7 @@ func TestReadBuffer_SetByteOrder(t *testing.T) {
                {
                        name: "set it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
        }
@@ -1973,7 +1971,7 @@ func TestReadBuffer_SetByteOrder(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -1985,7 +1983,7 @@ func TestReadBuffer_SetByteOrder(t *testing.T) {
 func TestReadBuffer_GetByteOrder(t *testing.T) {
        type fields struct {
                data      []uint8
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -1997,7 +1995,7 @@ func TestReadBuffer_GetByteOrder(t *testing.T) {
                {
                        name: "get it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                },
        }
@@ -2005,7 +2003,7 @@ func TestReadBuffer_GetByteOrder(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -2018,7 +2016,7 @@ func TestReadBuffer_GetByteOrder(t *testing.T) {
 func Test_byteReadBuffer_PullContext(t *testing.T) {
        type fields struct {
                data      []byte
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -2041,7 +2039,7 @@ func Test_byteReadBuffer_PullContext(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -2053,7 +2051,7 @@ func Test_byteReadBuffer_PullContext(t *testing.T) {
 func Test_byteReadBuffer_CloseContext(t *testing.T) {
        type fields struct {
                data      []byte
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -2076,7 +2074,7 @@ func Test_byteReadBuffer_CloseContext(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -2088,7 +2086,7 @@ func Test_byteReadBuffer_CloseContext(t *testing.T) {
 func Test_byteReadBuffer_ReadByte(t *testing.T) {
        type fields struct {
                data      []byte
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -2106,7 +2104,7 @@ func Test_byteReadBuffer_ReadByte(t *testing.T) {
                {
                        name: "read it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                        wantErr: assert.NoError,
                },
@@ -2115,7 +2113,7 @@ func Test_byteReadBuffer_ReadByte(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
@@ -2131,7 +2129,7 @@ func Test_byteReadBuffer_ReadByte(t *testing.T) {
 func Test_byteReadBuffer_ReadByteArray(t *testing.T) {
        type fields struct {
                data      []byte
-               reader    *bitio.Reader
+               bits      *ReadBitBuffer
                pos       uint64
                byteOrder binary.ByteOrder
        }
@@ -2150,7 +2148,7 @@ func Test_byteReadBuffer_ReadByteArray(t *testing.T) {
                {
                        name: "read  it",
                        fields: fields{
-                               reader: 
bitio.NewReader(bytes.NewBuffer([]byte{0x0})),
+                               bits: NewReadBitBuffer([]byte{0x0}),
                        },
                        args: args{
                                numberOfBytes: 1,
@@ -2163,7 +2161,7 @@ func Test_byteReadBuffer_ReadByteArray(t *testing.T) {
                t.Run(tt.name, func(t *testing.T) {
                        rb := &byteReadBuffer{
                                data:      tt.fields.data,
-                               reader:    tt.fields.reader,
+                               bits:      tt.fields.bits,
                                pos:       tt.fields.pos,
                                byteOrder: tt.fields.byteOrder,
                        }
diff --git a/plc4go/spi/utils/WriteBufferByteBased.go 
b/plc4go/spi/utils/WriteBufferByteBased.go
index be2d1d2ff2..64c2107a00 100644
--- a/plc4go/spi/utils/WriteBufferByteBased.go
+++ b/plc4go/spi/utils/WriteBufferByteBased.go
@@ -20,7 +20,6 @@
 package utils
 
 import (
-       "bytes"
        "context"
        "encoding/binary"
        "math"
@@ -29,7 +28,6 @@ import (
        "regexp"
        "strings"
 
-       "github.com/icza/bitio"
        "github.com/pkg/errors"
 )
 
@@ -41,11 +39,8 @@ type WriteBufferByteBased interface {
 }
 
 func NewWriteBufferByteBased(options ...WriteBufferByteBasedOptions) 
WriteBufferByteBased {
-       data := new(bytes.Buffer)
-       writer := bitio.NewWriter(data)
        b := &byteWriteBuffer{
-               data:      data,
-               writer:    writer,
+               bits:      NewWriteBitBuffer(0),
                byteOrder: binary.BigEndian,
        }
        for _, option := range options {
@@ -58,7 +53,9 @@ type WriteBufferByteBasedOptions = func(b *byteWriteBuffer)
 
 func WithInitialSizeForByteBasedBuffer(length int) WriteBufferByteBasedOptions 
{
        return func(b *byteWriteBuffer) {
-               b.data.Grow(length)
+               if cap(b.bits.buf) < length {
+                       b.bits.buf = make([]byte, 0, length)
+               }
        }
 }
 
@@ -68,13 +65,6 @@ func WithByteOrderForByteBasedBuffer(byteOrder 
binary.ByteOrder) WriteBufferByte
        }
 }
 
-func WithCustomBufferForByteBasedBuffer(buffer *bytes.Buffer) 
WriteBufferByteBasedOptions {
-       return func(b *byteWriteBuffer) {
-               b.data = buffer
-               b.writer = bitio.NewWriter(b.data)
-       }
-}
-
 ///////////////////////////////////////
 ///////////////////////////////////////
 //
@@ -83,13 +73,12 @@ func WithCustomBufferForByteBasedBuffer(buffer 
*bytes.Buffer) WriteBufferByteBas
 
 type byteWriteBuffer struct {
        BufferCommons
-       data      *bytes.Buffer
-       writer    *bitio.Writer
+       bits      *WriteBitBuffer
        byteOrder binary.ByteOrder
        pos       uint
 }
 
-var _ WriteBuffer = (*boxedWriteBuffer)(nil)
+var _ WriteBuffer = (*byteWriteBuffer)(nil)
 
 //
 // Internal section
@@ -114,27 +103,26 @@ func (wb *byteWriteBuffer) GetPos() uint16 {
 }
 
 func (wb *byteWriteBuffer) GetBytes() []byte {
-       return wb.data.Bytes()
+       return wb.bits.Bytes()
 }
 
 func (wb *byteWriteBuffer) GetTotalBytes() uint64 {
-       return uint64(wb.data.Len())
+       return uint64(wb.bits.ByteLen())
 }
 
 func (wb *byteWriteBuffer) WriteBit(_ string, value bool, _ ...WithWriterArgs) 
error {
        wb.move(1)
-       return wb.writer.WriteBool(value)
+       return wb.bits.WriteBool(value)
 }
 
 func (wb *byteWriteBuffer) WriteByte(_ string, value byte, _ 
...WithWriterArgs) error {
        wb.move(8)
-       return wb.writer.WriteBits(uint64(value), 8)
+       return wb.bits.WriteBits(uint64(value), 8)
 }
 
 func (wb *byteWriteBuffer) WriteByteArray(_ string, data []byte, _ 
...WithWriterArgs) error {
        for _, dataElement := range data {
-               err := wb.writer.WriteBits(uint64(dataElement), 8)
-               if err != nil {
+               if err := wb.bits.WriteBits(uint64(dataElement), 8); err != nil 
{
                        return err
                }
        }
@@ -144,66 +132,66 @@ func (wb *byteWriteBuffer) WriteByteArray(_ string, data 
[]byte, _ ...WithWriter
 
 func (wb *byteWriteBuffer) WriteUint8(_ string, bitLength uint8, value uint8, 
_ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteUint16(_ string, bitLength uint8, value 
uint16, _ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
        if wb.byteOrder == binary.LittleEndian {
                reverseValue := bits.ReverseBytes64(uint64(value)) >> (64 - 
bitLength)
-               return wb.writer.WriteBits(reverseValue, bitLength)
+               return wb.bits.WriteBits(reverseValue, bitLength)
        }
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteUint32(_ string, bitLength uint8, value 
uint32, _ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
        if wb.byteOrder == binary.LittleEndian {
                reverseValue := bits.ReverseBytes64(uint64(value)) >> (64 - 
bitLength)
-               return wb.writer.WriteBits(reverseValue, bitLength)
+               return wb.bits.WriteBits(reverseValue, bitLength)
        }
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteUint64(_ string, bitLength uint8, value 
uint64, _ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
        if wb.byteOrder == binary.LittleEndian {
                reverseValue := bits.ReverseBytes64(value) >> (64 - bitLength)
-               return wb.writer.WriteBits(reverseValue, bitLength)
+               return wb.bits.WriteBits(reverseValue, bitLength)
        }
-       return wb.writer.WriteBits(value, bitLength)
+       return wb.bits.WriteBits(value, bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteInt8(_ string, bitLength uint8, value int8, _ 
...WithWriterArgs) error {
        wb.move(uint(bitLength))
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteInt16(_ string, bitLength uint8, value int16, 
_ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
        if wb.byteOrder == binary.LittleEndian {
                reverseValue := bits.ReverseBytes64(uint64(value)) >> (64 - 
bitLength)
-               return wb.writer.WriteBits(reverseValue, bitLength)
+               return wb.bits.WriteBits(reverseValue, bitLength)
        }
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteInt32(_ string, bitLength uint8, value int32, 
_ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
        if wb.byteOrder == binary.LittleEndian {
                reverseValue := bits.ReverseBytes64(uint64(value)) >> (64 - 
bitLength)
-               return wb.writer.WriteBits(reverseValue, bitLength)
+               return wb.bits.WriteBits(reverseValue, bitLength)
        }
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteInt64(_ string, bitLength uint8, value int64, 
_ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
        if wb.byteOrder == binary.LittleEndian {
                reverseValue := bits.ReverseBytes64(uint64(value)) >> (64 - 
bitLength)
-               return wb.writer.WriteBits(reverseValue, bitLength)
+               return wb.bits.WriteBits(reverseValue, bitLength)
        }
-       return wb.writer.WriteBits(uint64(value), bitLength)
+       return wb.bits.WriteBits(uint64(value), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteBigInt(_ string, bitLength uint8, value 
*big.Int, _ ...WithWriterArgs) error {
@@ -213,24 +201,20 @@ func (wb *byteWriteBuffer) WriteBigInt(_ string, 
bitLength uint8, value *big.Int
 
 func (wb *byteWriteBuffer) WriteFloat32(_ string, bitLength uint8, value 
float32, _ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
+       res := math.Float32bits(value)
        if wb.byteOrder == binary.LittleEndian {
-               // TODO: indirection till we have a native LE implementation
-               // TODO: validate that this produces the desired result
-               return binary.Write(wb.data, wb.byteOrder, value)
+               res = bits.ReverseBytes32(res)
        }
-       res := math.Float32bits(value)
-       return wb.writer.WriteBits(uint64(res), bitLength)
+       return wb.bits.WriteBits(uint64(res), bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteFloat64(_ string, bitLength uint8, value 
float64, _ ...WithWriterArgs) error {
        wb.move(uint(bitLength))
+       res := math.Float64bits(value)
        if wb.byteOrder == binary.LittleEndian {
-               // TODO: indirection till we have a native LE implementation
-               // TODO: validate that this produces the desired result
-               return binary.Write(wb.data, wb.byteOrder, value)
+               res = bits.ReverseBytes64(res)
        }
-       res := math.Float64bits(value)
-       return wb.writer.WriteBits(res, bitLength)
+       return wb.bits.WriteBits(res, bitLength)
 }
 
 func (wb *byteWriteBuffer) WriteBigFloat(_ string, bitLength uint8, value 
*big.Float, _ ...WithWriterArgs) error {
@@ -249,7 +233,7 @@ func (wb *byteWriteBuffer) WriteString(_ string, bitLength 
uint32, value string,
        switch encoding {
        case "UTF8":
                for _, theByte := range []byte(value) {
-                       wb.writer.TryWriteByte(theByte)
+                       wb.bits.TryWriteByte(theByte)
                        remainingBits -= 8
                }
        case "UTF16":
@@ -257,23 +241,23 @@ func (wb *byteWriteBuffer) WriteString(_ string, 
bitLength uint32, value string,
        case "UTF16BE":
                // TODO: Really implement 2-byte characters
                for _, theByte := range []byte(value) {
-                       wb.writer.TryWriteByte(0x00)
-                       wb.writer.TryWriteByte(theByte)
+                       wb.bits.TryWriteByte(0x00)
+                       wb.bits.TryWriteByte(theByte)
                        remainingBits -= 16
                }
        case "UTF16LE":
                // TODO: Really implement 2-byte characters
                for _, theByte := range []byte(value) {
-                       wb.writer.TryWriteByte(theByte)
-                       wb.writer.TryWriteByte(0x00)
+                       wb.bits.TryWriteByte(theByte)
+                       wb.bits.TryWriteByte(0x00)
                        remainingBits -= 16
                }
        }
        // Fill up with 0-bytes
        for i := 0; i < int(remainingBits/8); i++ {
-               wb.writer.TryWriteByte(0x00)
+               wb.bits.TryWriteByte(0x00)
        }
-       return wb.writer.TryError
+       return wb.bits.GetTryError()
 }
 
 func (wb *byteWriteBuffer) WriteVirtual(ctx context.Context, logicalName 
string, value any, writerArgs ...WithWriterArgs) error {
diff --git a/plc4go/spi/utils/WriteBufferByteBased_test.go 
b/plc4go/spi/utils/WriteBufferByteBased_test.go
index 0f27b0c376..8916562f84 100644
--- a/plc4go/spi/utils/WriteBufferByteBased_test.go
+++ b/plc4go/spi/utils/WriteBufferByteBased_test.go
@@ -20,14 +20,12 @@
 package utils
 
 import (
-       "bytes"
        "context"
        "encoding/binary"
        "fmt"
        "math/big"
        "testing"
 
-       "github.com/icza/bitio"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
 )
@@ -63,8 +61,7 @@ func TestNewWriteBufferByteBased(t *testing.T) {
                {
                        name: "create it,",
                        want: &byteWriteBuffer{
-                               data:      new(bytes.Buffer),
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.BigEndian,
                        },
                },
@@ -94,34 +91,7 @@ func TestWithByteOrderForByteBasedBuffer(t *testing.T) {
                        assert.NotNilf(t, withByteOrderForByteBasedBuffer, 
"WithByteOrderForByteBasedBuffer(%v)", tt.args.byteOrder)
                        withByteOrderForByteBasedBuffer(
                                &byteWriteBuffer{
-                                       data:   new(bytes.Buffer),
-                                       writer: 
bitio.NewWriter(new(bytes.Buffer)),
-                               },
-                       )
-               })
-       }
-}
-
-func TestWithCustomBufferForByteBasedBuffer(t *testing.T) {
-       type args struct {
-               buffer *bytes.Buffer
-       }
-       tests := []struct {
-               name string
-               args args
-       }{
-               {
-                       name: "create it",
-               },
-       }
-       for _, tt := range tests {
-               t.Run(tt.name, func(t *testing.T) {
-                       withCustomBufferForByteBasedBuffer := 
WithCustomBufferForByteBasedBuffer(tt.args.buffer)
-                       assert.NotNilf(t, withCustomBufferForByteBasedBuffer, 
"WithCustomBufferForByteBasedBuffer(%v)", tt.args.buffer)
-                       withCustomBufferForByteBasedBuffer(
-                               &byteWriteBuffer{
-                                       data:   new(bytes.Buffer),
-                                       writer: 
bitio.NewWriter(new(bytes.Buffer)),
+                                       bits: NewWriteBitBuffer(0),
                                },
                        )
                })
@@ -146,8 +116,7 @@ func TestWithInitialSizeForByteBasedBuffer(t *testing.T) {
                        assert.NotNilf(t, withInitialSizeForByteBasedBuffer, 
"WithInitialSizeForByteBasedBuffer(%v)", tt.args.length)
                        withInitialSizeForByteBasedBuffer(
                                &byteWriteBuffer{
-                                       data:   new(bytes.Buffer),
-                                       writer: 
bitio.NewWriter(new(bytes.Buffer)),
+                                       bits: NewWriteBitBuffer(0),
                                },
                        )
                })
@@ -156,8 +125,7 @@ func TestWithInitialSizeForByteBasedBuffer(t *testing.T) {
 
 func Test_byteWriteBuffer_GetByteOrder(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -173,8 +141,7 @@ func Test_byteWriteBuffer_GetByteOrder(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -185,8 +152,7 @@ func Test_byteWriteBuffer_GetByteOrder(t *testing.T) {
 
 func Test_byteWriteBuffer_GetBytes(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -198,15 +164,15 @@ func Test_byteWriteBuffer_GetBytes(t *testing.T) {
                {
                        name: "get it",
                        fields: fields{
-                               data: new(bytes.Buffer),
+                               bits: NewWriteBitBuffer(0),
                        },
+                       want: []byte{},
                },
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -217,8 +183,7 @@ func Test_byteWriteBuffer_GetBytes(t *testing.T) {
 
 func Test_byteWriteBuffer_GetPos(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -234,8 +199,7 @@ func Test_byteWriteBuffer_GetPos(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -246,8 +210,7 @@ func Test_byteWriteBuffer_GetPos(t *testing.T) {
 
 func Test_byteWriteBuffer_GetTotalBytes(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -259,15 +222,14 @@ func Test_byteWriteBuffer_GetTotalBytes(t *testing.T) {
                {
                        name: "get it",
                        fields: fields{
-                               data: new(bytes.Buffer),
+                               bits: NewWriteBitBuffer(0),
                        },
                },
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -278,8 +240,7 @@ func Test_byteWriteBuffer_GetTotalBytes(t *testing.T) {
 
 func Test_byteWriteBuffer_PopContext(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -301,8 +262,7 @@ func Test_byteWriteBuffer_PopContext(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -313,8 +273,7 @@ func Test_byteWriteBuffer_PopContext(t *testing.T) {
 
 func Test_byteWriteBuffer_PushContext(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -336,8 +295,7 @@ func Test_byteWriteBuffer_PushContext(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -348,8 +306,7 @@ func Test_byteWriteBuffer_PushContext(t *testing.T) {
 
 func Test_byteWriteBuffer_SetByteOrder(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -368,8 +325,7 @@ func Test_byteWriteBuffer_SetByteOrder(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -380,8 +336,7 @@ func Test_byteWriteBuffer_SetByteOrder(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteBigFloat(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -405,8 +360,7 @@ func Test_byteWriteBuffer_WriteBigFloat(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -417,8 +371,7 @@ func Test_byteWriteBuffer_WriteBigFloat(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteBigInt(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -442,8 +395,7 @@ func Test_byteWriteBuffer_WriteBigInt(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -454,8 +406,7 @@ func Test_byteWriteBuffer_WriteBigInt(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteBit(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -473,7 +424,7 @@ func Test_byteWriteBuffer_WriteBit(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -481,8 +432,7 @@ func Test_byteWriteBuffer_WriteBit(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -493,8 +443,7 @@ func Test_byteWriteBuffer_WriteBit(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteByte(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -512,7 +461,7 @@ func Test_byteWriteBuffer_WriteByte(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -520,8 +469,7 @@ func Test_byteWriteBuffer_WriteByte(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -532,8 +480,7 @@ func Test_byteWriteBuffer_WriteByte(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteByteArray(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -551,14 +498,14 @@ func Test_byteWriteBuffer_WriteByteArray(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
                {
                        name: "write more",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        args: args{
                                data: []byte{1, 2, 3, 4},
@@ -569,8 +516,7 @@ func Test_byteWriteBuffer_WriteByteArray(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -581,8 +527,7 @@ func Test_byteWriteBuffer_WriteByteArray(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteFloat32(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -601,7 +546,7 @@ func Test_byteWriteBuffer_WriteFloat32(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -609,8 +554,7 @@ func Test_byteWriteBuffer_WriteFloat32(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -621,8 +565,7 @@ func Test_byteWriteBuffer_WriteFloat32(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteFloat64(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -641,7 +584,7 @@ func Test_byteWriteBuffer_WriteFloat64(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -649,8 +592,7 @@ func Test_byteWriteBuffer_WriteFloat64(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -661,8 +603,7 @@ func Test_byteWriteBuffer_WriteFloat64(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteInt16(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -681,14 +622,14 @@ func Test_byteWriteBuffer_WriteInt16(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
                {
                        name: "write it LE",
                        fields: fields{
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.LittleEndian,
                        },
                        wantErr: assert.NoError,
@@ -697,8 +638,7 @@ func Test_byteWriteBuffer_WriteInt16(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -709,8 +649,7 @@ func Test_byteWriteBuffer_WriteInt16(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteInt32(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -729,14 +668,14 @@ func Test_byteWriteBuffer_WriteInt32(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
                {
                        name: "write it LE",
                        fields: fields{
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.LittleEndian,
                        },
                        wantErr: assert.NoError,
@@ -745,8 +684,7 @@ func Test_byteWriteBuffer_WriteInt32(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -757,8 +695,7 @@ func Test_byteWriteBuffer_WriteInt32(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteInt64(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -777,14 +714,14 @@ func Test_byteWriteBuffer_WriteInt64(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
                {
                        name: "write it LE",
                        fields: fields{
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.LittleEndian,
                        },
                        wantErr: assert.NoError,
@@ -793,8 +730,7 @@ func Test_byteWriteBuffer_WriteInt64(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -805,8 +741,7 @@ func Test_byteWriteBuffer_WriteInt64(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteInt8(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -825,7 +760,7 @@ func Test_byteWriteBuffer_WriteInt8(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -833,8 +768,7 @@ func Test_byteWriteBuffer_WriteInt8(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -845,8 +779,7 @@ func Test_byteWriteBuffer_WriteInt8(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteSerializable(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -864,14 +797,14 @@ func Test_byteWriteBuffer_WriteSerializable(t *testing.T) 
{
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        setup: func(t *testing.T, fields *fields, args *args) {
                                serializable := NewMockSerializable(t)
@@ -887,8 +820,7 @@ func Test_byteWriteBuffer_WriteSerializable(t *testing.T) {
                                tt.setup(t, &tt.fields, &tt.args)
                        }
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -899,8 +831,7 @@ func Test_byteWriteBuffer_WriteSerializable(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteString(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -919,7 +850,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        args: args{
                                bitLength: 48,
@@ -930,7 +861,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
                {
                        name: "write it UTF-8",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        args: args{
                                bitLength: 48,
@@ -942,7 +873,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
                {
                        name: "write it UTF-16",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        args: args{
                                bitLength: 48,
@@ -954,7 +885,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
                {
                        name: "write it UTF-16 BigEndian",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        args: args{
                                bitLength: 48,
@@ -966,7 +897,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
                {
                        name: "write it UTF-16 LittleEndian",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        args: args{
                                bitLength: 48,
@@ -979,8 +910,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -991,8 +921,7 @@ func Test_byteWriteBuffer_WriteString(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteUint16(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -1011,14 +940,14 @@ func Test_byteWriteBuffer_WriteUint16(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
                {
                        name: "write it LE",
                        fields: fields{
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.LittleEndian,
                        },
                        wantErr: assert.NoError,
@@ -1027,8 +956,7 @@ func Test_byteWriteBuffer_WriteUint16(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -1039,8 +967,7 @@ func Test_byteWriteBuffer_WriteUint16(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteUint32(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -1059,7 +986,7 @@ func Test_byteWriteBuffer_WriteUint32(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -1067,7 +994,7 @@ func Test_byteWriteBuffer_WriteUint32(t *testing.T) {
                {
                        name: "write it LE",
                        fields: fields{
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.LittleEndian,
                        },
                        wantErr: assert.NoError,
@@ -1076,8 +1003,7 @@ func Test_byteWriteBuffer_WriteUint32(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -1088,8 +1014,7 @@ func Test_byteWriteBuffer_WriteUint32(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteUint64(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -1108,7 +1033,7 @@ func Test_byteWriteBuffer_WriteUint64(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -1116,7 +1041,7 @@ func Test_byteWriteBuffer_WriteUint64(t *testing.T) {
                {
                        name: "write it LE",
                        fields: fields{
-                               writer:    bitio.NewWriter(new(bytes.Buffer)),
+                               bits:      NewWriteBitBuffer(0),
                                byteOrder: binary.LittleEndian,
                        },
                        wantErr: assert.NoError,
@@ -1125,8 +1050,7 @@ func Test_byteWriteBuffer_WriteUint64(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -1137,8 +1061,7 @@ func Test_byteWriteBuffer_WriteUint64(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteUint8(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -1157,7 +1080,7 @@ func Test_byteWriteBuffer_WriteUint8(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -1165,8 +1088,7 @@ func Test_byteWriteBuffer_WriteUint8(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -1177,8 +1099,7 @@ func Test_byteWriteBuffer_WriteUint8(t *testing.T) {
 
 func Test_byteWriteBuffer_WriteVirtual(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -1197,7 +1118,7 @@ func Test_byteWriteBuffer_WriteVirtual(t *testing.T) {
                {
                        name: "write it",
                        fields: fields{
-                               writer: bitio.NewWriter(new(bytes.Buffer)),
+                               bits: NewWriteBitBuffer(0),
                        },
                        wantErr: assert.NoError,
                },
@@ -1205,8 +1126,7 @@ func Test_byteWriteBuffer_WriteVirtual(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }
@@ -1217,8 +1137,7 @@ func Test_byteWriteBuffer_WriteVirtual(t *testing.T) {
 
 func Test_byteWriteBuffer_move(t *testing.T) {
        type fields struct {
-               data      *bytes.Buffer
-               writer    *bitio.Writer
+               bits      *WriteBitBuffer
                byteOrder binary.ByteOrder
                pos       uint
        }
@@ -1237,8 +1156,7 @@ func Test_byteWriteBuffer_move(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        wb := &byteWriteBuffer{
-                               data:      tt.fields.data,
-                               writer:    tt.fields.writer,
+                               bits:      tt.fields.bits,
                                byteOrder: tt.fields.byteOrder,
                                pos:       tt.fields.pos,
                        }

Reply via email to