Source code for pcapkit.utilities.decorators

# -*- coding: utf-8 -*-
# pylint: disable=protected-access
"""decorator functions

:mod:`pcapkit.utilities.decorators` contains several useful
decorators, including :func:`~pcapkit.utilities.decorators.seekset`
and :func:`~pcapkit.utilities.decorators.beholder`.

"""
import functools
import io
import os
import traceback

###############################################################################
# from pcapkit.foundation.analysis import analyse
# from pcapkit.protocols.raw import Raw
###############################################################################

__all__ = ['seekset', 'seekset_ng', 'beholder', 'beholder_ng']


[docs]def seekset(func): """Read file from start then set back to original. Important: This decorator function is designed for decorating *class methods*. The decorator will keep the current offset of :attr:`self._file`, then call the decorated function. Afterwards, it will rewind the offset of :attr:`self._file` to the original and returns the return value from the decorated function. Note: The decorated function should have following signature:: func(self, *args, **kw) See Also: :meth:`pcapkit.protocols.protocol.Protocol._read_packet` :meta decorator: """ @functools.wraps(func) def seekcur(self, *args, **kw): seek_cur = self._file.tell() self._file.seek(self._seekset, os.SEEK_SET) return_ = func(self, *args, **kw) self._file.seek(seek_cur, os.SEEK_SET) return return_ return seekcur
[docs]def seekset_ng(func): """Read file from start then set back to original. Important: This decorator function is designed for decorating *plain functions*. The decorator will rewind the offset of ``file`` to ``seekset``, then call the decorated function and returns its return value. Note: The decorated function should have following signature:: func(file, *args, seekset=os.SEEK_SET, **kw) See Also: :mod:`pcapkit.foundation.analysis` :meta decorator: """ @functools.wraps(func) def seekcur(file, *args, seekset=os.SEEK_SET, **kw): # pylint: disable=redefined-outer-name # seek_cur = file.tell() file.seek(seekset, os.SEEK_SET) return_ = func(file, *args, seekset=seekset, **kw) # file.seek(seek_cur, os.SEEK_SET) return return_ return seekcur
[docs]def beholder(func): """Behold extraction procedure. Important: This decorator function is designed for decorating *class methods*. This decorate first keep the current offset of :attr:`self._file <pcapkit.protocols.protocol.Protocol._file>`, then try to call the decorated function. Should any exception raised, it will re-parse the :attr:`self._file <pcapkit.protocols.protocol.Protocol._file>` as :class:`~pcapkit.protocols.raw.Raw` protocol. Note: The decorated function should have following signature:: func(self, proto, length, *args, **kwargs) See Also: :meth:`pcapkit.protocols.protocol.Protocol._decode_next_layer` :meta decorator: """ @functools.wraps(func) def behold(self, proto, length, *args, **kwargs): seek_cur = self._file.tell() try: return func(proto, length, *args, **kwargs) except Exception: from pcapkit.protocols.raw import Raw # pylint: disable=import-outside-toplevel error = traceback.format_exc(limit=1).strip().split(os.linesep)[-1] # error = traceback.format_exc() self._file.seek(seek_cur, os.SEEK_SET) next_ = Raw(io.BytesIO(self._read_fileng(length)), length, error=error) return next_ return behold
[docs]def beholder_ng(func): """Behold analysis procedure. Important: This decorator function is designed for decorating *plain functions*. This decorate first keep the current offset of ``file``, then try to call the decorated function. Should any exception raised, it will re-parse the ``file`` as :class:`~pcapkit.protocols.raw.Raw` protocol. Note: The decorated function should have following signature:: func(file, length, *args, **kwargs) See Also: :meth:`pcapkit.protocols.transport.transport.Transport._import_next_layer` :meta decorator: """ @functools.wraps(func) def behold(file, length, *args, **kwargs): seek_cur = file.tell() try: return func(file, length, *args, **kwargs) except Exception: # from pcapkit.foundation.analysis import analyse from pcapkit.protocols.raw import Raw # pylint: disable=import-outside-toplevel error = traceback.format_exc(limit=1).strip().split(os.linesep)[-1] # error = traceback.format_exc() file.seek(seek_cur, os.SEEK_SET) # raw = Raw(file, length, error=str(error)) # return analyse(raw.info, raw.protochain, raw.alias) next_ = Raw(file, length, error=error) return next_ return behold