ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

(this is more of an addition to @ahendrix's answer (but I didn't want to edit his))

See the (de)serialisation code for UInt8.msg for how this works in Python fi:

  def serialize(self, buff):
    """
    serialize message into buffer
    :param buff: buffer, ``StringIO``
    """
    try:
      buff.write(_get_struct_B().pack(self.data))
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
    except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(locals().get('_x', self)))))

  def deserialize(self, str):
    """
    unpack serialized message in str into this message instance
    :param str: byte array of serialized message, ``str``
    """
    try:
      end = 0
      start = end
      end += 1
      (self.data,) = _get_struct_B().unpack(str[start:end])
      return self
    except struct.error as e:
      raise genpy.DeserializationError(e) #most likely buffer underfill

At least at this level (and this is the ony place message content is actually (de)serialised), values that are unrepresentable by the type that was specced for a field in a message will result in exceptions being thrown.

(this is more of an addition to @ahendrix's answer (but I didn't want to edit his))

See the (de)serialisation code for UInt8.msg for how this works in Python fi:fi (taken from /opt/ros/kinetic/lib/python2.7/dist-packages/std_msgs/msg/_UInt8.py):

  def serialize(self, buff):
    """
    serialize message into buffer
    :param buff: buffer, ``StringIO``
    """
    try:
      buff.write(_get_struct_B().pack(self.data))
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
    except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(locals().get('_x', self)))))

  def deserialize(self, str):
    """
    unpack serialized message in str into this message instance
    :param str: byte array of serialized message, ``str``
    """
    try:
      end = 0
      start = end
      end += 1
      (self.data,) = _get_struct_B().unpack(str[start:end])
      return self
    except struct.error as e:
      raise genpy.DeserializationError(e) #most likely buffer underfill

At least at this level (and this is the ony place message content is actually (de)serialised), values that are unrepresentable by the type that was specced for a field in a message will result in exceptions being thrown.

@ahendrix wrote:

I believe Python is using the struct library to pack objects into the serialization format, so you will get an exception if the value in that message field is outside of the allowed bounds.

Exactly: _get_struct_B() essentially just returns an instance of struct.Struct("B"):

def _get_struct_B():
    global _struct_B
    if _struct_B is None:
        _struct_B = struct.Struct("<B")
    return _struct_B

Note also the endianness specification there.

(this is more of an addition to @ahendrix's answer (but I didn't want to edit his))

See the (de)serialisation code for UInt8.msg for how this works in Python fi (taken from /opt/ros/kinetic/lib/python2.7/dist-packages/std_msgs/msg/_UInt8.py):

  def serialize(self, buff):
    """
    serialize message into buffer
    :param buff: buffer, ``StringIO``
    """
    try:
      buff.write(_get_struct_B().pack(self.data))
    except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(locals().get('_x', self)))))
    except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(locals().get('_x', self)))))

  def deserialize(self, str):
    """
    unpack serialized message in str into this message instance
    :param str: byte array of serialized message, ``str``
    """
    try:
      end = 0
      start = end
      end += 1
      (self.data,) = _get_struct_B().unpack(str[start:end])
      return self
    except struct.error as e:
      raise genpy.DeserializationError(e) #most likely buffer underfill

At least at this level (and this is the ony place message content is actually (de)serialised), (de)serialised, called from here and here), values that are unrepresentable by the type that was specced for a field in a message will result in exceptions being thrown.

@ahendrix wrote:

I believe Python is using the struct library to pack objects into the serialization format, so you will get an exception if the value in that message field is outside of the allowed bounds.

Exactly: _get_struct_B() essentially just returns an instance of struct.Struct("B"):

def _get_struct_B():
    global _struct_B
    if _struct_B is None:
        _struct_B = struct.Struct("<B")
    return _struct_B

Note also the endianness specification there.