code: def read(self, fieldname):
          
          if self._pos == -1:
              self._pos = 0
              if PREFIX['message'] != self.stream.read(1):
                  raise SendlibError('Invalid message format')
              if PREFIX['str'] != self.stream.read(1):
                  raise SendlibError('Invalid message format')
              name = self._read_str()
              if PREFIX['int'] != self.stream.read(1):
                  raise SendlibError('Invalid message format')
              version = self._read_int()
              if name != self.message.name or version != self.message.version:
                  raise SendlibError(
                      'Reader for %s cannot read message of type (%s, %d)'
                      % (self.message, name, version))
  
          if self._data is not None:
              if self._data.bytes_remaining() == 0:
                  self._data = None
              else:
                  raise Exception('cannot read field, cursor still on data')
  
          if self._peek is None:
              self._peek = self.stream.read(1)
          typename = self._check(fieldname)
          reader = getattr(self, '_read_' + typename)
          value = reader()
          self._pos += 1
          self._peek = None
          return value
docs: Read the next field from the stream. `fieldname` is used
          to verify that your application logic matches the message
          field order, and if `fieldname` does not match the next
          field in the message definition, :class:`SendlibError`
          is raised.
  
          Returns a Python object of the correct type, depending on
          the type present in the stream. If the type is ``data``,
          returns a :class:`Data` file-like object.