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 dbd320ac92288555209363f12430c00915fcb336 Author: Sebastian Rühl <[email protected]> AuthorDate: Mon May 18 17:00:53 2026 +0200 fix(plc4go): reader writer todos --- plc4go/spi/utils/ReadBufferByteBased.go | 80 ++++++++++---------------------- plc4go/spi/utils/WriteBufferByteBased.go | 33 ++++++------- 2 files changed, 40 insertions(+), 73 deletions(-) diff --git a/plc4go/spi/utils/ReadBufferByteBased.go b/plc4go/spi/utils/ReadBufferByteBased.go index db4755c5f7..bc961c87c9 100644 --- a/plc4go/spi/utils/ReadBufferByteBased.go +++ b/plc4go/spi/utils/ReadBufferByteBased.go @@ -23,6 +23,7 @@ import ( "encoding/binary" "math" "math/big" + "math/bits" "github.com/pkg/errors" ) @@ -145,54 +146,39 @@ func (rb *byteReadBuffer) ReadUint8(_ string, bitLength uint8, _ ...WithReaderAr return uint8(res), nil } -func (rb *byteReadBuffer) ReadUint16(logicalName string, bitLength uint8, _ ...WithReaderArgs) (uint16, error) { - if rb.byteOrder == binary.LittleEndian { - // TODO: indirection till we have a native LE implementation - bigInt, err := rb.ReadBigInt(logicalName, uint64(bitLength)) - if err != nil { - return 0, err - } - return uint16(bigInt.Uint64()), nil - } +func (rb *byteReadBuffer) ReadUint16(_ string, bitLength uint8, _ ...WithReaderArgs) (uint16, error) { 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) } rb.pos += uint64(bitLength) + if rb.byteOrder == binary.LittleEndian { + return uint16(bits.ReverseBytes64(res) >> (64 - bitLength)), nil + } return uint16(res), nil } -func (rb *byteReadBuffer) ReadUint32(logicalName string, bitLength uint8, _ ...WithReaderArgs) (uint32, error) { - if rb.byteOrder == binary.LittleEndian { - // TODO: indirection till we have a native LE implementation - bigInt, err := rb.ReadBigInt(logicalName, uint64(bitLength)) - if err != nil { - return 0, err - } - return uint32(bigInt.Uint64()), nil - } +func (rb *byteReadBuffer) ReadUint32(_ string, bitLength uint8, _ ...WithReaderArgs) (uint32, error) { 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) } rb.pos += uint64(bitLength) + if rb.byteOrder == binary.LittleEndian { + return uint32(bits.ReverseBytes64(res) >> (64 - bitLength)), nil + } return uint32(res), nil } -func (rb *byteReadBuffer) ReadUint64(logicalName string, bitLength uint8, _ ...WithReaderArgs) (uint64, error) { - if rb.byteOrder == binary.LittleEndian { - // TODO: indirection till we have a native LE implementation - bigInt, err := rb.ReadBigInt(logicalName, uint64(bitLength)) - if err != nil { - return 0, err - } - return bigInt.Uint64(), nil - } +func (rb *byteReadBuffer) ReadUint64(_ string, bitLength uint8, _ ...WithReaderArgs) (uint64, error) { 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) } rb.pos += uint64(bitLength) + if rb.byteOrder == binary.LittleEndian { + return bits.ReverseBytes64(res) >> (64 - bitLength), nil + } return res, nil } @@ -205,59 +191,43 @@ func (rb *byteReadBuffer) ReadInt8(_ string, bitLength uint8, _ ...WithReaderArg return int8(res), nil } -func (rb *byteReadBuffer) ReadInt16(logicalName string, bitLength uint8, _ ...WithReaderArgs) (int16, error) { - if rb.byteOrder == binary.LittleEndian { - // TODO: indirection till we have a native LE implementation - bigInt, err := rb.ReadBigInt(logicalName, uint64(bitLength)) - if err != nil { - return 0, err - } - return int16(bigInt.Int64()), nil - } +func (rb *byteReadBuffer) ReadInt16(_ string, bitLength uint8, _ ...WithReaderArgs) (int16, error) { 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) } rb.pos += uint64(bitLength) + if rb.byteOrder == binary.LittleEndian { + return int16(bits.ReverseBytes64(res) >> (64 - bitLength)), nil + } return int16(res), nil } -func (rb *byteReadBuffer) ReadInt32(logicalName string, bitLength uint8, _ ...WithReaderArgs) (int32, error) { - if rb.byteOrder == binary.LittleEndian { - // TODO: indirection till we have a native LE implementation - bigInt, err := rb.ReadBigInt(logicalName, uint64(bitLength)) - if err != nil { - return 0, err - } - return int32(bigInt.Int64()), nil - } +func (rb *byteReadBuffer) ReadInt32(_ string, bitLength uint8, _ ...WithReaderArgs) (int32, error) { 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) } rb.pos += uint64(bitLength) + if rb.byteOrder == binary.LittleEndian { + return int32(bits.ReverseBytes64(res) >> (64 - bitLength)), nil + } return int32(res), nil } -func (rb *byteReadBuffer) ReadInt64(logicalName string, bitLength uint8, _ ...WithReaderArgs) (int64, error) { - if rb.byteOrder == binary.LittleEndian { - // TODO: indirection till we have a native LE implementation - bigInt, err := rb.ReadBigInt(logicalName, uint64(bitLength)) - if err != nil { - return 0, err - } - return bigInt.Int64(), nil - } +func (rb *byteReadBuffer) ReadInt64(_ string, bitLength uint8, _ ...WithReaderArgs) (int64, error) { 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) } rb.pos += uint64(bitLength) + if rb.byteOrder == binary.LittleEndian { + return int64(bits.ReverseBytes64(res) >> (64 - bitLength)), nil + } return int64(res), nil } func (rb *byteReadBuffer) ReadBigInt(_ string, bitLength uint64, _ ...WithReaderArgs) (*big.Int, error) { - // TODO: highly experimental remove this comment when tested or verified rawBytes := make([]byte, 0, (bitLength+7)/8) fullBytes := bitLength / 8 diff --git a/plc4go/spi/utils/WriteBufferByteBased.go b/plc4go/spi/utils/WriteBufferByteBased.go index 64c2107a00..0a325ee077 100644 --- a/plc4go/spi/utils/WriteBufferByteBased.go +++ b/plc4go/spi/utils/WriteBufferByteBased.go @@ -27,10 +27,13 @@ import ( "math/bits" "regexp" "strings" + "unicode/utf16" "github.com/pkg/errors" ) +var nonAlphanumericRegex = regexp.MustCompile(`[^A-Z0-9]+`) + type WriteBufferByteBased interface { WriteBuffer GetPos() uint16 @@ -224,37 +227,31 @@ func (wb *byteWriteBuffer) WriteBigFloat(_ string, bitLength uint8, value *big.F func (wb *byteWriteBuffer) WriteString(_ string, bitLength uint32, value string, writerArgs ...WithWriterArgs) error { wb.move(uint(bitLength)) - // TODO: make this a writer arg - var nonAlphanumericRegex = regexp.MustCompile(`[^A-Z0-9]+`) - encoding := wb.ExtractEncoding(UpcastWriterArgs(writerArgs...)...) - encoding = nonAlphanumericRegex.ReplaceAllLiteralString(strings.ToUpper(encoding), "") - remainingBits := int64(bitLength) // we use int64 otherwise the subtraction below flips - // TODO: the implementation completely ignores encoding for now. Fix this + encoding := nonAlphanumericRegex.ReplaceAllLiteralString(strings.ToUpper(wb.ExtractEncoding(UpcastWriterArgs(writerArgs...)...)), "") + remainingBits := int64(bitLength) // int64 so subtraction doesn't wrap on underflow switch encoding { case "UTF8": - for _, theByte := range []byte(value) { - wb.bits.TryWriteByte(theByte) + for _, b := range []byte(value) { + wb.bits.TryWriteByte(b) remainingBits -= 8 } case "UTF16": fallthrough case "UTF16BE": - // TODO: Really implement 2-byte characters - for _, theByte := range []byte(value) { - wb.bits.TryWriteByte(0x00) - wb.bits.TryWriteByte(theByte) + for _, u := range utf16.Encode([]rune(value)) { + wb.bits.TryWriteByte(byte(u >> 8)) + wb.bits.TryWriteByte(byte(u)) remainingBits -= 16 } case "UTF16LE": - // TODO: Really implement 2-byte characters - for _, theByte := range []byte(value) { - wb.bits.TryWriteByte(theByte) - wb.bits.TryWriteByte(0x00) + for _, u := range utf16.Encode([]rune(value)) { + wb.bits.TryWriteByte(byte(u)) + wb.bits.TryWriteByte(byte(u >> 8)) remainingBits -= 16 } } - // Fill up with 0-bytes - for i := 0; i < int(remainingBits/8); i++ { + // Fill remaining allocated space with zero bytes + for range remainingBits / 8 { wb.bits.TryWriteByte(0x00) } return wb.bits.GetTryError()
