diff --git a/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py b/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py index a04d71af514..78d094b47eb 100644 --- a/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py +++ b/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py @@ -119,18 +119,18 @@ def push_context(self, logical_name: str, **kwargs) -> None: # byte buffer need no context handling pass - def write_bit(self, value: c_bool, logical_name: str = "", *kwargs) -> None: + def write_bit(self, value: c_bool, logical_name: str = "", **kwargs) -> None: self.bb[self.position] = bool(value) self.position += 1 - def write_byte(self, value: c_byte, logical_name: str = "", *kwargs) -> None: + def write_byte(self, value: c_byte, logical_name: str = "", **kwargs) -> None: self.write_signed_byte(value, logical_name, **kwargs) - def write_byte_array(self, value: List[c_byte], logical_name: str = "", *kwargs) -> None: + def write_byte_array(self, value: List[c_byte], logical_name: str = "", **kwargs) -> None: for aByte in value: self.write_signed_byte(aByte, logical_name, **kwargs) - def write_unsigned_byte(self, value: c_byte, bit_length: int = 8, logical_name: str = "", *kwargs) -> None: + def write_unsigned_byte(self, value: c_byte, bit_length: int = 8, logical_name: str = "", **kwargs) -> None: if bit_length <= 0: raise SerializationException("unsigned byte can only contain max 8 bits") elif bit_length > 8: @@ -141,23 +141,28 @@ def write_unsigned_byte(self, value: c_byte, bit_length: int = 8, logical_name: self.bb[self.position:bit_length] = src[:bit_length] self.position += bit_length - # def write_unsigned_short(self, value: c_uint16, bit_length: int = 16, logical_name: str = "", *kwargs) -> None: - # if bit_length <= 0: - # raise SerializationException("unsigned short can only contain max 8 bits") - # elif bit_length > 8: - # raise SerializationException("unsigned short can only contain max 16 bits") - # else: - # self.bb.append(bytes(value)) - # value_encoding: str = kwargs.get("encoding", "default") - # if value_encoding == "ASCII": - # if bit_length % 8 != 0: - # raise SerializationException("'ASCII' encoded fields must have a length that is a multiple of 8 bits long") - # char_len: int = int(bit_length / 8) - # max_value: int = int(10**char_len - 1) - # if value > max_value: - # raise SerializationException("Provided value of " + str(value) + " exceeds the max value of " + str(max_value)) - # string_value: str = "{}".format(value) - # self.bb.append(string_value) - # elif value_encoding == "default": - # self.bb[self.position:bit_length] = value - # self.postion += bit_length + def write_unsigned_short(self, value: c_uint16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None: + if bit_length <= 0: + raise SerializationException("unsigned short can only contain max 8 bits") + elif bit_length > 16: + raise SerializationException("unsigned short can only contain max 16 bits") + else: + value_encoding: str = kwargs.get("encoding", "default") + if value_encoding == "ASCII": + if bit_length % 8 != 0: + raise SerializationException("'ASCII' encoded fields must have a length that is a multiple of 8 bits long") + char_len: int = int(bit_length / 8) + max_value: int = int(10**char_len - 1) + if value > max_value: + raise SerializationException("Provided value of " + str(value) + " exceeds the max value of " + str(max_value)) + string_value: str = "{}".format(value) + + src = bitarray(endian=ByteOrder.get_short_name(self.byte_order)) + src.frombytes(string_value) + self.bb[self.position:bit_length] = src[:bit_length] + self.position += bit_length + elif value_encoding == "default": + src = bitarray(endian=ByteOrder.get_short_name(self.byte_order)) + src.frombytes(value) + self.bb[self.position:bit_length] = src[:bit_length] + self.position += bit_length diff --git a/sandbox/plc4py/plc4py/spi/values/Common.py b/sandbox/plc4py/plc4py/spi/values/Common.py index 77a7351cdfe..886a61162eb 100644 --- a/sandbox/plc4py/plc4py/spi/values/Common.py +++ b/sandbox/plc4py/plc4py/spi/values/Common.py @@ -1,3 +1,22 @@ +# +# 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. +# + from plc4py.spi.generation import WriteBuffer diff --git a/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py b/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py index 3a2284dc8af..68f357913c3 100644 --- a/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py +++ b/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. # -from ctypes import c_bool, c_byte +from ctypes import c_bool, c_byte, c_uint16 import pytest from bitarray import bitarray @@ -115,4 +115,16 @@ def test_write_buffer_set_unsigned_byte_big_endian(mocker) -> None: wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.BIG_ENDIAN) wb.write_unsigned_byte(c_byte(0x12), 4, "Test String 1") ba: memoryview = wb.get_bytes() - assert (ba.obj == bitarray("00010000")) \ No newline at end of file + assert (ba.obj == bitarray("00010000")) + +def test_write_buffer_write_unsigned_short_big_endian(mocker) -> None: + wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.LITTLE_ENDIAN) + wb.write_unsigned_short(c_uint16(0x12), 16, "Test String 1") + ba: memoryview = wb.get_bytes() + assert (ba.obj == bitarray("00010010 00000000", endian="little")) + +def test_write_buffer_write_unsigned_short_big_endian(mocker) -> None: + wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.BIG_ENDIAN) + wb.write_unsigned_short(c_uint16(0x12), 16, "Test String 1") + ba: memoryview = wb.get_bytes() + assert (ba.obj == bitarray("00010010 00000000", endian="big"))