more flexible end_of_line in stringio
in the previous version, it was not possible to give a ASCII nul character as end_of_line, because StringType refuses this - end_of_line might be given as bytes, str or int - end_of_line might be given as tuple (eol_read, eol_write) Change-Id: I8b7942320ad3ffe162cdf3a673e113a66a84fb93 Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/23496 Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de> Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de> Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
parent
1655e252fc
commit
a520e6e1e4
@ -28,7 +28,7 @@ import threading
|
|||||||
import re
|
import re
|
||||||
from secop.lib.asynconn import AsynConn, ConnectionClosed
|
from secop.lib.asynconn import AsynConn, ConnectionClosed
|
||||||
from secop.modules import Module, Communicator, Parameter, Command, Property, Attached
|
from secop.modules import Module, Communicator, Parameter, Command, Property, Attached
|
||||||
from secop.datatypes import StringType, FloatRange, ArrayOf, BoolType, TupleOf
|
from secop.datatypes import StringType, FloatRange, ArrayOf, BoolType, TupleOf, ValueType
|
||||||
from secop.errors import CommunicationFailedError, CommunicationSilentError
|
from secop.errors import CommunicationFailedError, CommunicationSilentError
|
||||||
from secop.poller import REGULAR
|
from secop.poller import REGULAR
|
||||||
from secop.metaclass import Done
|
from secop.metaclass import Done
|
||||||
@ -43,7 +43,7 @@ class StringIO(Communicator):
|
|||||||
'uri':
|
'uri':
|
||||||
Property('hostname:portnumber', datatype=StringType()),
|
Property('hostname:portnumber', datatype=StringType()),
|
||||||
'end_of_line':
|
'end_of_line':
|
||||||
Property('end_of_line character', datatype=StringType(),
|
Property('end_of_line character', datatype=ValueType(),
|
||||||
default='\n', settable=True),
|
default='\n', settable=True),
|
||||||
'encoding':
|
'encoding':
|
||||||
Property('used encoding', datatype=StringType(),
|
Property('used encoding', datatype=StringType(),
|
||||||
@ -73,13 +73,32 @@ class StringIO(Communicator):
|
|||||||
def earlyInit(self):
|
def earlyInit(self):
|
||||||
self._conn = None
|
self._conn = None
|
||||||
self._lock = threading.RLock()
|
self._lock = threading.RLock()
|
||||||
self._end_of_line = self.end_of_line.encode(self.encoding)
|
eol = self.end_of_line
|
||||||
|
if isinstance(eol, (tuple, list)):
|
||||||
|
if len(eol) not in (1, 2):
|
||||||
|
raise ValueError('invalid end_of_line: %s' % eol)
|
||||||
|
else:
|
||||||
|
eol = [eol]
|
||||||
|
# eol for read and write might be distinct
|
||||||
|
self._eol_read = self._convert_eol(eol[0])
|
||||||
|
if not self._eol_read:
|
||||||
|
raise ValueError('end_of_line for read must not be empty')
|
||||||
|
self._eol_write = self._convert_eol(eol[-1])
|
||||||
self._last_error = None
|
self._last_error = None
|
||||||
|
|
||||||
|
def _convert_eol(self, value):
|
||||||
|
if isinstance(value, str):
|
||||||
|
return value.encode(self.encoding)
|
||||||
|
if isinstance(value, int):
|
||||||
|
return bytes([value])
|
||||||
|
if isinstance(value, bytes):
|
||||||
|
return value
|
||||||
|
raise ValueError('invalid end_of_line: %s' % repr(value))
|
||||||
|
|
||||||
def connectStart(self):
|
def connectStart(self):
|
||||||
if not self.is_connected:
|
if not self.is_connected:
|
||||||
uri = self.uri
|
uri = self.uri
|
||||||
self._conn = AsynConn(uri, self._end_of_line)
|
self._conn = AsynConn(uri, self._eol_read)
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
for command, regexp in self.identification:
|
for command, regexp in self.identification:
|
||||||
reply = self.do_communicate(command)
|
reply = self.do_communicate(command)
|
||||||
@ -159,10 +178,10 @@ class StringIO(Communicator):
|
|||||||
try:
|
try:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
# read garbage and wait before send
|
# read garbage and wait before send
|
||||||
if self.wait_before:
|
if self.wait_before and self._eol_write:
|
||||||
cmds = command.split(self.end_of_line)
|
cmds = command.encode(self.encoding).split(self._eol_write)
|
||||||
else:
|
else:
|
||||||
cmds = [command]
|
cmds = [command.encode(self.encoding)]
|
||||||
garbage = None
|
garbage = None
|
||||||
try:
|
try:
|
||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
@ -171,8 +190,8 @@ class StringIO(Communicator):
|
|||||||
if garbage is None: # read garbage only once
|
if garbage is None: # read garbage only once
|
||||||
garbage = self._conn.flush_recv()
|
garbage = self._conn.flush_recv()
|
||||||
if garbage:
|
if garbage:
|
||||||
self.log.debug('garbage: %s', garbage.decode(self.encoding))
|
self.log.debug('garbage: %r', garbage)
|
||||||
self._conn.send((cmd + self.end_of_line).encode(self.encoding))
|
self._conn.send(cmd + self._eol_write)
|
||||||
reply = self._conn.readline(self.timeout)
|
reply = self._conn.readline(self.timeout)
|
||||||
except ConnectionClosed:
|
except ConnectionClosed:
|
||||||
self.closeConnection()
|
self.closeConnection()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user