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.

def read(self, fieldname):
        """
        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.
        """
        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