예제 #1
0
    def __iter__(self):  # pylint: disable=too-many-branches
        """Iterate over messages in the file"""
        logger.debug("Starting File Read")
        logger.debug("File Position: %d File Counter: %d File Name: %s",
                     self.file_position, self.counter, self.filename)
        cached_mtime = 0
        cached_file_pos = 0
        corruption_check_try = True

        self._open_file()

        found_data = False
        while not self.stop_reading.isSet() or corruption_check_try:  # pylint: disable=too-many-nested-blocks
            os_stat = os.stat(self.filename)
            mtime = os_stat.st_mtime

            if mtime != cached_mtime and os_stat.st_size or corruption_check_try:
                cached_mtime = mtime
                corruption_check_try = False

                while dltlib.dlt_file_read(ctypes.byref(self), self.verbose) >= DLT_RETURN_OK:
                    found_data = True
                    if self.filter and dltlib.dlt_message_filter_check(
                            ctypes.byref(self.msg), self.filter, 0) != DLT_RETURN_TRUE:
                        continue

                    index = self.position
                    msg = self[index]
                    if not index % 100000:
                        self._log_message_progress()
                    yield msg

                if cached_file_pos != self.file_position:
                    # We were able to read messages, don't do a corrupt message check yet.
                    corruption_check_try = True
                    cached_file_pos = self.file_position
                else:
                    next_header_position = self._find_next_header()
                    if next_header_position:
                        if self.file_position == next_header_position:
                            if not self.live_run:
                                logger.warning("Incomplete message while parsing DLT file at %s", self.file_position)
                                break
                        else:
                            logger.warning("Found a corrupt message at %s, skipping it", self.file_position)
                            self.file_position = next_header_position
                            self.corrupt_msg_count += 1
                            corruption_check_try = True
                    # Wait for further messages to determine if corrupt, else just end of file
                    else:
                        if not self.live_run:
                            logger.info("End of file reached at %s", self.file_position)
                            break

            time.sleep(0.1)

        if not found_data:
            raise IOError(DLT_EMPTY_FILE_ERROR)
예제 #2
0
    def generate_index(self):
        """Generate an index for the loaded DLT file

        :returns: True if file had been previously read and the index is
                  successfully generated, otherwise False
        :rtype: bool
        """
        if not self.filename:
            return False

        self.indexed = False
        if dltlib.dlt_file_open(ctypes.byref(self), self.filename,
                                self.verbose) >= DLT_RETURN_OK:
            # load, analyse data file and create index list
            if self.file_length == 0:
                raise IOError(DLT_EMPTY_FILE_ERROR)
            while self.file_position < self.file_length:
                ret = dltlib.dlt_file_read(ctypes.byref(self), self.verbose)
                if ret < DLT_RETURN_OK:
                    # - This can happen if either the frame's storage
                    # header could not be read correctly or the frame is
                    # corrupt. If the frame's storage header could not
                    # be read correctly we try to get the next storage
                    # header and continue indexing
                    next_header_position = self._find_next_header()
                    if next_header_position:
                        if self.file_position == next_header_position:  # pylint: disable=no-else-break
                            # - This this implies that dltlib.dlt_read_file()
                            # returned due to an error other than invalid storage
                            # header because we already were at the correct
                            # header_position in the last iteration. So, we
                            # need to break out of the read/index loop.
                            break
                        else:
                            self.file_position = next_header_position
                            self.corrupt_msg_count += 1
                    else:
                        break
            self.indexed = True
        else:
            raise IOError(cDLT_FILE_NOT_OPEN_ERROR)
        return self.indexed