Source code for canlib.kvmlib.logfile

import ctypes as ct
import datetime
from functools import wraps

from .enums import LogFileType
from .events import memoLogEventEx
from .exceptions import KvmNoLogMsg
from .wrapper import dll


[docs]class LogFile: """A log file read from a `MountedLog` object This class is normally not directly instantiated but retrieved from a `MountedLog` object. The most common use of this class is iterating through it to get the individual events as `LogEvent` subclasses:: for event in logfile: ... Note: While iterating over a `LogFile`, accessing any other `LogFile` is will result in a `LockedLogError`. Make sure to finish the loop (or when using iteration objects directly call the `close` method) before interacting with any other log files. A fast approximation of the number of events is given by `event_count_estimation`, the exact number of events can be calculated using:: num_events = len(list(logfile)) Finally this class has several read-only properties for getting information about the log file itself. Note: Before any data is fetched from the dll, this class will make sure that the correct file has been mounted on the underlying ``kvmHandle``. Manually mounting or unmounting log files by calling the dll directly is not supported. .. versionadded:: 1.6 """ def _mounted_handle(func): @wraps(func) def wrapper(self, *args, **kwargs): cont = self._container if cont._mounted_index != self.index: self._remount() return func(self, cont.handle, *args, **kwargs) return wrapper def __init__(self, container, index): self._container = container self.index = index def __iter__(self): # force a remount, to reset the dll's internal event counter self._remount() try: self._container._mount_lock = True while True: # It is currently up to the user to make sure the handle/device # stays mounted on this file during iteration. eventstruct = memoLogEventEx() dll.kvmLogFileReadEvent(self._container.handle, ct.byref(eventstruct)) event = eventstruct.createMemoEvent() yield event except (KvmNoLogMsg, GeneratorExit): # GeneratorExit is raised when close() is called on this # generator. This means that if we iterate over the LogFile # manually (it = iter(LogFile) and then next(it)) we can also # release the lock when we close it (it.close()) self._container._mount_lock = False return @property @_mounted_handle def creator_serial(self, handle): """`int`: The serial number of the interface that created the log file""" serial = ct.c_uint32() dll.kvmLogFileGetCreatorSerial(handle, ct.byref(serial)) return serial.value @property @_mounted_handle def end_time(self, handle): """`datetime.datetime`: The time of the last event in the log file""" time = ct.c_uint32() dll.kvmLogFileGetEndTime(handle, ct.byref(time)) return datetime.datetime.fromtimestamp(time.value) @property @_mounted_handle def start_time(self, handle): """`datetime.datetime`: The time of the first event in the log file""" time = ct.c_uint32() dll.kvmLogFileGetStartTime(handle, ct.byref(time)) return datetime.datetime.fromtimestamp(time.value) @property @_mounted_handle def log_type(self, handle): """`~canlib.kvmlib.enums.LogFileType`: The type of the log file .. versionadded:: 1.11 """ type_ = ct.c_int32() dll.kvmLogFileGetType(handle, self.index, ct.byref(type_)) return LogFileType(type_.value)
[docs] def event_count_estimation(self): """Returns an approximation of the number of events The number is a rough estimation because it is calculated from the number of blocks allocated by the log file on the disk as an optimization. .. versionadded:: 1.7 """ # The only way to get the event count approximation from the underlying # dll is during mounting (in kvmLogFileMountEx()) return self._remount()
def _remount(self): return self._container._mount(self.index)