Skip to content

Commit

Permalink
Merge #454
Browse files Browse the repository at this point in the history
454: Fix binary read for empty header r=MatthieuDartiailh a=MatthieuDartiailh

Closes #452

Co-authored-by: MatthieuDartiailh <marul@laposte.net>
  • Loading branch information
bors[bot] and MatthieuDartiailh committed Aug 28, 2019
2 parents 8aa27b5 + 498a483 commit 20a2d26
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
8 changes: 8 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ PyVISA Changelog
-----------------


1.10.1 (unreleased)
-----------------

- Fix reading binary values with an empty header PR #454
- Allow to use different headers in write_binary_values PR #454
- Remove delay kwarg from read_ascii_values which should never have been there PR #454


1.10 (2019-08-09)
-----------------

Expand Down
38 changes: 25 additions & 13 deletions pyvisa/resources/messagebased.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ def write(self, message, termination=None, encoding=None):
:param message: the message to be sent.
:type message: unicode (Py2) or str (Py3)
:param termination: alternative character termination to use.
:type termination: unicode (Py2) or str (Py3)
:param encoding: encoding to convert from unicode to bytes.
:type encoding: unicode (Py2) or str (Py3)
:return: number of bytes written.
:rtype: int
"""
Expand Down Expand Up @@ -237,7 +241,7 @@ def write_ascii_values(self, message, values, converter='f', separator=',',
:param values: data to be writen to the device.
:param converter: function used to convert each value.
String formatting codes are also accepted.
Defaults to str.
Defaults to 'f'.
:type converter: callable | str
:param separator: a callable that join the values in a single str.
If a str is given, separator.join(values) is used.
Expand Down Expand Up @@ -266,7 +270,7 @@ def write_ascii_values(self, message, values, converter='f', separator=',',

def write_binary_values(self, message, values, datatype='f',
is_big_endian=False, termination=None,
encoding=None):
encoding=None, header_fmt='ieee'):
"""Write a string message to the device followed by values in binary
format.
Expand All @@ -278,6 +282,8 @@ def write_binary_values(self, message, values, datatype='f',
:param datatype: the format string for a single element. See struct
module.
:param is_big_endian: boolean indicating endianess.
:param header_fmt: format of the header prefixing the data. Possible
values are: 'ieee', 'hp', 'empty'
:return: number of bytes written.
:rtype: int
"""
Expand All @@ -288,7 +294,14 @@ def write_binary_values(self, message, values, datatype='f',
warnings.warn("write message already ends with "
"termination characters", stacklevel=2)

block = util.to_ieee_block(values, datatype, is_big_endian)
if header_fmt == "ieee":
block = util.to_ieee_block(values, datatype, is_big_endian)
elif header_fmt == "hp":
block = util.to_hp_block(values, datatype, is_big_endian)
elif header_fmt =="empty":
block = util.to_binary_block(values, b"", datatype, is_big_endian)
else:
raise ValueError("Unsupported header_fmt: %s" % header_fmt)

message = message.encode(enco) + block

Expand Down Expand Up @@ -425,8 +438,7 @@ def read(self, termination=None, encoding=None):

return message[:-len(termination)]

def read_ascii_values(self, converter='f', separator=',', container=list,
delay=None):
def read_ascii_values(self, converter='f', separator=',', container=list):
"""Read values from the device in ascii format returning an iterable of
values.
Expand Down Expand Up @@ -483,19 +495,20 @@ def read_binary_values(self, datatype='f', is_big_endian=False,
if header_fmt == 'ieee':
offset, data_length = util.parse_ieee_block_header(block)

# Allow to support instrument such as the Keithley 2000 that do not
# report the length of the block
data_length = data_length or data_points*struct.calcsize(datatype)

elif header_fmt == 'hp':
offset, data_length = util.parse_hp_block_header(block,
is_big_endian)
elif header == 'empty':
elif header_fmt == 'empty':
offset = 0
data_length = 0
else:
raise ValueError("Invalid header format. Valid options are 'ieee',"
" 'empty', 'hp'")

# Allow to support instrument such as the Keithley 2000 that do not
# report the length of the block
data_length = data_length or data_points*struct.calcsize(datatype)

expected_length = offset + data_length

if expect_termination and self._read_termination is not None:
Expand All @@ -515,7 +528,7 @@ def read_binary_values(self, datatype='f', is_big_endian=False,
'as part of the transfer, it may be because the size is '
'fixed or can be accessed from the instrumentin using a '
'specific command. You should find the expected number of '
'bytes and pass it using the `data_length` keyword.')
'points and pass it using the `data_points` keyword.')
warnings.warn(msg, FutureWarning)
# Do not keep reading since we may have already read everything

Expand Down Expand Up @@ -656,8 +669,7 @@ def query_ascii_values(self, message, converter='f', separator=',',
if delay > 0.0:
time.sleep(delay)

return self.read_ascii_values(converter, separator, container,
delay)
return self.read_ascii_values(converter, separator, container)

def query_binary_values(self, message, datatype='f', is_big_endian=False,
container=list, delay=None, header_fmt='ieee',
Expand Down

0 comments on commit 20a2d26

Please sign in to comment.