Skip to content

Commit

Permalink
Implemented smarter query values based on looking how many bytes are …
Browse files Browse the repository at this point in the history
…expected

See #118
  • Loading branch information
hgrecco committed Feb 18, 2015
1 parent a424332 commit 4bcf1bb
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 19 deletions.
29 changes: 18 additions & 11 deletions pyvisa/resources/messagebased.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .. import logger
from .. import constants
from .. import errors
from ..util import from_ascii_block, parse_binary, from_ieee_block, to_ieee_block, to_ascii_block, from_binary_block
from .. import util

from .resource import Resource

Expand Down Expand Up @@ -211,7 +211,7 @@ def write_ascii_values(self, message, values, converter='f', separator=',', term
warnings.warn("write message already ends with "
"termination characters", stacklevel=2)

block = to_ascii_block(values, converter, separator)
block = util.to_ascii_block(values, converter, separator)

message = message.encode(enco) + block

Expand Down Expand Up @@ -242,7 +242,7 @@ def write_binary_values(self, message, values, datatype='f', is_big_endian=False
warnings.warn("write message already ends with "
"termination characters", stacklevel=2)

block = to_ieee_block(values, datatype, is_big_endian)
block = util.to_ieee_block(values, datatype, is_big_endian)

message = message.encode(enco) + block

Expand Down Expand Up @@ -335,10 +335,10 @@ def read_values(self, fmt=None, container=list):
if not fmt:
vf = self.values_format
if not vf.is_binary:
return from_ascii_block(self.read(), container)
return util.from_ascii_block(self.read(), container)
data = self.read_raw()
try:
return parse_binary(data, vf.is_big_endian, vf.datatype=='f')
return util.parse_binary(data, vf.is_big_endian, vf.datatype=='f')
except ValueError as e:
try:
msg = e.args[0]
Expand All @@ -347,7 +347,7 @@ def read_values(self, fmt=None, container=list):
raise errors.InvalidBinaryFormat(msg)

if fmt & 0x01 == 0: # ascii
return from_ascii_block(self.read())
return util.from_ascii_block(self.read())

data = self.read_raw()

Expand All @@ -360,7 +360,7 @@ def read_values(self, fmt=None, container=list):
raise ValueError("unknown data values fmt requested")

is_big_endian = fmt & 0x04 # big endian
return parse_binary(data, is_big_endian, is_single)
return util.parse_binary(data, is_big_endian, is_single)
except ValueError as e:
raise errors.InvalidBinaryFormat(e.args)

Expand Down Expand Up @@ -431,7 +431,7 @@ def query_ascii_values(self, message, converter='f', separator=',', container=li

block = self.read()

return from_ascii_block(block, converter, separator, container)
return util.from_ascii_block(block, converter, separator, container)

def query_binary_values(self, message, datatype='f', is_big_endian=False, container=list, delay=None, header_fmt='ieee'):
"""Converts an iterable of numbers into a block of data in the ieee format.
Expand All @@ -457,13 +457,20 @@ def query_binary_values(self, message, datatype='f', is_big_endian=False, contai

block = self.read_raw()

if header_fmt == 'ieee':
offset, data_length = util.parse_ieee_block_header(block)
expected_length = offset + data_length

while len(block) < expected_length:
block += self.read_raw()

try:
if header_fmt == 'ieee':
return from_ieee_block(block, datatype, is_big_endian, container)
return util.from_ieee_block(block, datatype, is_big_endian, container)
elif header_fmt == 'empty':
return from_binary_block(block, 0, None, datatype, is_big_endian, container)
return util.from_binary_block(block, 0, None, datatype, is_big_endian, container)
elif header_fmt == 'hp':
return from_binary_block(block, 4, None, datatype, is_big_endian, container)
return util.from_binary_block(block, 4, None, datatype, is_big_endian, container)
except ValueError as e:
raise errors.InvalidBinaryFormat(e.args)

Expand Down
42 changes: 34 additions & 8 deletions pyvisa/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ def parse_binary(bytes_data, is_big_endian=False, is_single=False):
return result


def from_ieee_block(block, datatype='f', is_big_endian=False, container=list):
"""Convert a block in the IEEE format into an iterable of numbers.
def parse_ieee_block_header(block):
"""Parse the header of a IEEE block.
Definite Length Arbitrary Block:
#<header_length><data_length><data>
Expand All @@ -285,13 +285,9 @@ def from_ieee_block(block, datatype='f', is_big_endian=False, container=list):
:param block: IEEE block.
:type block: bytes
:param datatype: the format string for a single element. See struct module.
:param is_big_endian: boolean indicating endianess.
:param container: container type to use for the output data.
:return: items
:rtype: type(container)
:return: (offset, data_length)
:rtype: (int, int)
"""

begin = block.find(b'#')
if begin < 0:
raise ValueError("Could not find hash sign (#) indicating the start of the block.")
Expand All @@ -313,6 +309,36 @@ def from_ieee_block(block, datatype='f', is_big_endian=False, container=list):
# 012
data_length = len(block) - offset - 1

return offset, data_length


def from_ieee_block(block, datatype='f', is_big_endian=False, container=list):
"""Convert a block in the IEEE format into an iterable of numbers.
Definite Length Arbitrary Block:
#<header_length><data_length><data>
The header_length specifies the size of the data_length field.
And the data_length field specifies the size of the data.
Indefinite Length Arbitrary Block:
#0<data>
:param block: IEEE block.
:type block: bytes
:param datatype: the format string for a single element. See struct module.
:param is_big_endian: boolean indicating endianess.
:param container: container type to use for the output data.
:return: items
:rtype: type(container)
"""

offset, data_length = parse_ieee_block_header(block)

if len(block) < offset + data_length:
raise ValueError("Binary data is incomplete. The header states %d data bytes, "
"but %d where received." % (data_length, len(block) - offset))

return from_binary_block(block, offset, data_length, datatype, is_big_endian, container)


Expand Down

0 comments on commit 4bcf1bb

Please sign in to comment.