Запись непосредственно в буфер поля битов - PullRequest
0 голосов
/ 28 июня 2018

Я работаю над структурой полей битов из ctypes в Python, и у меня есть вопрос. Можно ли записать напрямую в буфер пакета Packet ниже определенного?

from ctypes import c_uint8

class PacketBits(ctypes.LittleEndianStructure):
  _fields_ = [
      # First byte
      ("a", ctypes.c_uint8, 4),
      ("b", ctypes.c_uint8, 3),
      ("c", ctypes.c_uint8, 1),
      # Second byte
      ("d", ctypes.c_uint8, 5),
      ("e", ctypes.c_uint8, 3),
      # Third byte
      ("f", ctypes.c_uint8, 4),
      ("g", ctypes.c_uint8, 4),
      # Fourth byte
      ("h", ctypes.c_uint8, 2),
      ("i", ctypes.c_uint8, 6),
      # Fifth byte
      ("j", ctypes.c_uint8, 4),
      ("k", ctypes.c_uint8, 3),
      ("l", ctypes.c_uint8, 1),
      # Sixth byte
      ("m", ctypes.c_uint8, 5),
      ("n", ctypes.c_uint8, 3),
      # Seventh byte
      ("o", ctypes.c_uint8, 4),
      ("p", ctypes.c_uint8, 4),
      # Eighth byte
      ("q", ctypes.c_uint8, 2),
      ("r", ctypes.c_uint8, 6),
  ]

class Packet(ctypes.Union):
    _fields_ = [("bits", PacketBits),
                ("binary_data", 8 * c_uint8)]

Я задаю этот вопрос, потому что мне нужно проанализировать поток из 65 байтов с некоторыми определениями битов внутри.

Я пытался установить его напрямую, с помощью bitarray, ... и все методы, которые я пробовал, были неудачными.

У кого-нибудь есть идея?

С уважением.

Юхан

1 Ответ

0 голосов
/ 29 июня 2018

Я нашел решение, я использовал setter и getter в классе Packet:

class Packet(ctypes.Union):
    _fields_ = [("bits", PacketBits),
                ("binary_data", 8 * ctypes.c_uint8)]

    def get_binary_data(self):
        data = []
        for byte in self.binary_data:
            data.append(byte) 

        return data

    def set_binary_data(self, data = b'\x0D\x0E\x0A\x0D\x0B\x0E\x0E\x0F'):
        if len(data) <= len(self.binary_data):
            for index in range(len(data)):
                self.binary_data[index] = data[index]

Но теперь, когда я создаю экземпляр класса Packet, у меня есть доступ к двоичным_данным, установщикам и получателям.

Тогда есть два доступа к двоичным_данным.

Я хочу разрешить один доступ (по сеттеру и геттеру), затем я попытался со свойством, подобным этому:

class Packet(ctypes.Union):
    _fields_ = [("bits", PacketBits),
                ("binary_data", 8 * ctypes.c_uint8)]

    @property
    def binary_data(self):
        data = []
        for byte in self.binary_data:
            data.append(byte) 

        return data

    @binary_data.setter
    def binary_data(self, data = b'\x0D\x0E\x0A\x0D\x0B\x0E\x0E\x0F'):
        if len(data) <= len(self.binary_data):
            for index in range(len(data)):
                self.binary_data[index] = data[index]

In [2]: p = Packet()

In [3]: p.binary_data()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-5caaf0aaa9ce> in <module>()
----> 1 p.binary_data()

TypeError: 'c_ubyte_Array_8' object is not callable

In [4]: p.binary_data
Out[4]: <test.c_ubyte_Array_8 at 0x7f7d538bf400>

In [5]: p.binary_data = b'\xaa'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-6a26479e789c> in <module>()
----> 1 p.binary_data = b'\xaa'

TypeError: expected c_ubyte_Array_8 instance, got bytes

У кого-нибудь есть идеи, как правильно использовать свойство и сеттер?

Юхан

...