Skip to content

Commit 3a1f1b8

Browse files
committed
Optional length validation on binary conversion
1 parent 99665a6 commit 3a1f1b8

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

harp/io.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,11 @@ def read(
139139

140140

141141
def to_file(
142-
file: _FileLike,
143142
data: pd.DataFrame,
143+
file: _FileLike,
144144
address: int,
145145
dtype: Optional[np.dtype] = None,
146+
length: Optional[int] = None,
146147
port: Optional[int] = None,
147148
epoch: Optional[datetime] = None,
148149
message_type: Optional[MessageType] = None,
@@ -151,16 +152,19 @@ def to_file(
151152
152153
Parameters
153154
----------
155+
data
156+
Pandas data frame containing message payload.
154157
file
155158
File path, or open file object in which to store binary data from
156159
a single device register.
157-
data
158-
Pandas data frame containing message payload.
159160
address
160161
Register address used to identify all formatted Harp messages.
161162
dtype
162163
Data type of the register payload. If specified, all data will
163164
be converted before formatting the binary payload.
165+
length
166+
Expected number of elements in register payload. If specified, the
167+
number of columns in the input data frame is validated.
164168
port
165169
Optional port value used for all formatted Harp messages.
166170
epoch
@@ -170,14 +174,15 @@ def to_file(
170174
Optional message type used for all formatted Harp messages.
171175
If not specified, data must contain a MessageType column.
172176
"""
173-
buffer = to_buffer(data, address, dtype, port, epoch, message_type)
177+
buffer = to_buffer(data, address, dtype, port, length, epoch, message_type)
174178
buffer.tofile(file)
175179

176180

177181
def to_buffer(
178182
data: pd.DataFrame,
179183
address: int,
180184
dtype: Optional[np.dtype] = None,
185+
length: Optional[int] = None,
181186
port: Optional[int] = None,
182187
epoch: Optional[datetime] = None,
183188
message_type: Optional[MessageType] = None,
@@ -193,6 +198,9 @@ def to_buffer(
193198
dtype
194199
Data type of the register payload. If specified, all data will
195200
be converted before formatting the binary payload.
201+
length
202+
Expected number of elements in register payload. If specified, the
203+
number of columns in the input data frame is validated.
196204
port
197205
Optional port value used for all formatted Harp messages.
198206
epoch
@@ -207,7 +215,8 @@ def to_buffer(
207215
An array object containing message data formatted according
208216
to the Harp binary protocol.
209217
"""
210-
if len(data) == 0:
218+
nrows = len(data)
219+
if nrows == 0:
211220
return np.empty(0, dtype=np.uint8)
212221

213222
if "MessageType" in data.columns:
@@ -231,17 +240,20 @@ def to_buffer(
231240
if dtype is not None:
232241
payload = payload.astype(dtype, copy=False)
233242

243+
ncols = payload.shape[1]
244+
if length is not None and ncols != length:
245+
raise ValueError(f"expected payload length {length} but got {ncols}")
246+
234247
if port is None:
235248
port = 255
236249

237250
payloadtype = _payloadtypefromdtype[payload.dtype]
238-
payloadlength = payload.shape[1] * payload.dtype.itemsize
251+
payloadlength = ncols * payload.dtype.itemsize
239252
stride = payloadlength + 6
240253
if is_timestamped:
241254
payloadtype |= _PAYLOAD_TIMESTAMP_MASK
242255
stride += 6
243256

244-
nrows = len(data)
245257
buffer = np.empty((nrows, stride), dtype=np.uint8)
246258
buffer[:, 0] = msgtype
247259
buffer[:, 1:5] = [stride - 2, address, port, payloadtype]

tests/test_io.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,5 @@ def test_write(dataFile: DataFileParam):
8484
keep_type=dataFile.keep_type,
8585
)
8686
assert len(data) == dataFile.expected_rows
87-
write_buffer = to_buffer(data, address=dataFile.expected_address)
87+
write_buffer = to_buffer(data, address=dataFile.expected_address, length=dataFile.expected_length)
8888
assert np.array_equal(buffer, write_buffer)

0 commit comments

Comments
 (0)