Skip to content

Commit

Permalink
feat(plc4py): Add initial signed int
Browse files Browse the repository at this point in the history
  • Loading branch information
hutcheb committed May 12, 2023
1 parent 5ae793e commit e14a3d7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
20 changes: 14 additions & 6 deletions sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
Expand Up @@ -14,7 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from ctypes import c_bool, c_byte, c_ubyte, c_uint16, c_uint32, c_uint64, c_int16, c_int32, c_int64, c_float, c_double
from ctypes import c_bool, c_byte, c_ubyte, c_uint16, c_uint32, c_uint64, c_int16, c_int32, c_int64, c_float, c_double, \
c_int8
from dataclasses import dataclass
from typing import List

Expand Down Expand Up @@ -65,7 +66,7 @@ def write_unsigned_int(self, value: c_uint32, bit_length: int = 32, logical_name
def write_unsigned_long(self, value: c_uint64, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
raise NotImplementedError

def write_signed_byte(self, value: c_byte, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
def write_signed_byte(self, value: c_int8, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
raise NotImplementedError

def write_short(self, value: c_int16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None:
Expand Down Expand Up @@ -135,10 +136,7 @@ def write_unsigned_byte(self, value: c_byte, bit_length: int = 8, logical_name:
elif bit_length > 8:
raise SerializationException("unsigned byte can only contain max 8 bits")
else:
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
self._handle_integer_encoding(c_byte(value.value), bit_length, **kwargs)

def write_unsigned_short(self, value: c_uint16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None:
if bit_length <= 0:
Expand Down Expand Up @@ -185,3 +183,13 @@ def _handle_integer_encoding(self, value, bit_length: int, **kwargs):
src.frombytes(value)
self.bb[self.position:bit_length] = src[:bit_length]
self.position += bit_length

def write_signed_byte(self, value: c_int8, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
if bit_length <= 0:
raise SerializationException("Signed byte must contain at least 1 bit")
elif bit_length > 8:
raise SerializationException("Signed byte can only contain max 8 bits")
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
20 changes: 18 additions & 2 deletions sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py
Expand Up @@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
from ctypes import c_bool, c_byte, c_uint16, c_uint64
from ctypes import c_bool, c_byte, c_uint16, c_uint64, c_int8

import pytest
from bitarray import bitarray
Expand Down Expand Up @@ -215,8 +215,24 @@ def test_write_buffer_write_unsigned_long_ascii_encoding_little_endian(mocker) -
assert (ba.obj == bitarray("10001100 10001100 10001100 10001100 10001100 10001100 10001100 10001100", endian="little"))


def test_write_buffer_write_unsigned_short_ascii_encoding_big_endian(mocker) -> None:
def test_write_buffer_write_unsigned_long_ascii_encoding_big_endian(mocker) -> None:
wb: WriteBufferByteBased = WriteBufferByteBased(8, ByteOrder.BIG_ENDIAN)
wb.write_unsigned_long(c_uint64(11111111), 64, "ASCII Value of 1111 1111 - 0x3131313131313131", encoding="ASCII")
ba: memoryview = wb.get_bytes()
assert (ba.obj == bitarray("00110001 00110001 00110001 00110001 00110001 00110001 00110001 00110001", endian="big"))


def test_write_buffer_set_signed_byte(mocker) -> None:
wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
wb.write_signed_byte(c_int8(-1), 8)
ba: memoryview = wb.get_bytes()
assert (ba.obj == bitarray("11111111",
endian="little"))


def test_write_buffer_set_signed_byte_three(mocker) -> None:
wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
wb.write_signed_byte(c_int8(3), 8)
ba: memoryview = wb.get_bytes()
assert (ba.obj == bitarray("11000000",
endian="little"))

0 comments on commit e14a3d7

Please sign in to comment.