def _read(self, f):
        """Parse an NDEF record from a file-like object."""
        
        try:
            self.header = ord(f.read(1))
        except TypeError:
            log.debug("buffer underflow at offset {0}".format(f.tell()))
            raise LengthError("insufficient data to parse")
        
        mbf = bool(self.header & 0x80)
        mef = bool(self.header & 0x40)
        cff = bool(self.header & 0x20)
        srf = bool(self.header & 0x10)
        ilf = bool(self.header & 0x08)
        tnf = self.header & 0x07

        try:
            type_length = ord(f.read(1))
            if srf: # short record
                data_length = ord(f.read(1))
            else: # 32-bit length
                data_length = struct.unpack('>L', f.read(4))[0]
            if ilf: # id length present
                name_length = ord(f.read(1))
            else:
                name_length = 0
        except (TypeError, struct.error):
            log.debug("buffer underflow at offset {0}".format(f.tell()))
            raise LengthError("insufficient data to parse")

        try:
            record_type = f.read(type_length)
            assert len(record_type) == type_length
            record_name = f.read(name_length)
            assert len(record_name) == name_length
            record_data = f.read(data_length)
            assert len(record_data) == data_length
        except AssertionError:
            log.debug("buffer underflow at offset {0}".format(f.tell()))
            raise LengthError("insufficient data to parse")

        if tnf in (0, 5, 6) and len(record_type) > 0:
            s = "ndef type name format {0} doesn't allow a type string"
            raise FormatError( s.format(tnf) )
        if tnf in (1, 2, 3, 4) and len(record_type) == 0:
            s = "ndef type name format {0} requires a type string"
            raise FormatError( s.format(tnf) )
        if tnf == 0 and len(record_data) > 0:
            s = "ndef type name format {0} doesn't allow a payload"
            raise FormatError( s.format(tnf) )
            
        self._message_begin, self._message_end = mbf, mef
        self._type = bytearray(type_name_prefix[tnf] + record_type)
        self._name = bytearray(record_name)
        self._data = bytearray(record_data)
        log.debug("parsed {0}".format(repr(self)))
Parse an NDEF record from a file-like object.