@@ -247,12 +247,11 @@ class EpicsString:
247247 _dbf_type_ = fields .DBF_STRING
248248
249249 def _value_to_epics (self , value ):
250- if isinstance (value , str ):
251- value = value .encode ()
252250 # It's a little odd: we can't simply construct a value from the byte
253- # string, but we can update the array in an existing value
251+ # string, but we can update the array in an existing value.
252+ # Value being written must be a string.
254253 result = self ._ctype_ ()
255- result .value = value
254+ result .value = value . encode ()
256255 return result
257256
258257 def _epics_to_value (self , epics ):
@@ -345,17 +344,6 @@ def _compare_values(self, value, other):
345344 return numpy .all (value == other )
346345
347346 def _value_to_epics (self , value ):
348- '''Handles strings and bytearrays as values for Waveforms. Returns the
349- string converted to a numpy array.'''
350- if isinstance (value , str ):
351- value = value .encode (errors = 'replace' )
352- if isinstance (value , bytes ):
353- # Convert a string into an array of characters. This will produce
354- # the correct behaviour when treating a character array as a string.
355- # Note that the trailing null is needed to work around problems with
356- # some clients. Note this also exists in builder.py's _waveform().
357- value = numpy .frombuffer (value + b'\0 ' , dtype = numpy .uint8 )
358-
359347 # Ensure we always convert incoming value into numpy array, regardless
360348 # of whether the record has been initialised or not
361349 value = numpy .require (value , dtype = self .dtype )
@@ -390,5 +378,39 @@ class waveform_out(WaveformBase, ProcessDeviceSupportOut):
390378 _device_name_ = 'devPython_waveform_out'
391379
392380
381+ # Convert string into numpy array of char
382+ def encode_string (value , length = None ):
383+ value = value .encode (errors = 'replace' )
384+ # Convert a string into an array of characters. This will produce
385+ # the correct behaviour when treating a character array as a string.
386+ # Note that the trailing null is needed to work around problems with
387+ # some clients.
388+ value = numpy .frombuffer (value + b'\0 ' , dtype = numpy .uint8 )
389+
390+ # Truncate value to fit
391+ if length :
392+ value = value [:length ]
393+ return value
394+
395+
396+ class LongStringBase (WaveformBase ):
397+ dtype = numpy .dtype ('uint8' )
398+
399+ def _value_to_epics (self , value ):
400+ return encode_string (value , getattr (self , '_nelm' , None ))
401+
402+ def _epics_to_value (self , value ):
403+ return value .decode (errors = 'replace' )
404+
405+
406+ class long_stringin (LongStringBase , ProcessDeviceSupportIn ):
407+ _record_type_ = 'waveform'
408+ _device_name_ = 'devPython_long_stringin'
409+
410+ class long_stringout (LongStringBase , ProcessDeviceSupportOut ):
411+ _record_type_ = 'waveform'
412+ _device_name_ = 'devPython_long_stringout'
413+
414+
393415# Ensure the .dbd file is loaded.
394416dbLoadDatabase ('device.dbd' , os .path .dirname (__file__ ), None )
0 commit comments