# Utilities Manual

&emsp; `jspcap` is an open source library for PCAP extraction and analysis, written in __Python 3.6__. The following is a manual for utility functions and classes.

 - [Decorators](#decorators)
 	* [`seekset`](#seekset)
    * [`seekset_ng`](#seekset_ng)
    * [`beholder`](#beholder)
    * [`beholder_ng`](#beholder_ng)
 - [Validations](#validations)
    * [Module Index](#index-validations)
    * [Module Notes](#notes-validations)
 - [Exceptions](#exceptions)
    * [`BaseError`](#baseerror)
    * [Refined Exceptions](#refined-exceptions)

---

## Decorators

 > described in [`src/utilities/decorators.py`](https://github.com/JarryShaw/jspcap/tree/master/src/utilities/decorators.py)

&emsp; `jspcap.utilities.decorators` contains several useful decorators, including `seekset` and `beholder`.

### `seekset`

```python
def seekset(func):
    def seekcur(self, *args, **kwargs):
        ...
        return func(self, *args, **kwargs)
    return seekcur
```

##### Read file from start then set back to original.

__NOTE__: this decorator works with class methods, which has a *file-like* attribute names `self._file`.

### `seekset_ng`

```python
def seekset_ng(func):
    def seekcur(file, *args, **kwargs):
        ...
        return func(file, *args, **kwargs)
    return seekcur
```

##### Read file from start then set back to original.

__NOTE__: positional argument `file` in `seekcur` must be a *file-like* object.

### `beholder`

```python
def beholder(func):
    def behold(self, proto, length, *args, **kwargs):
        ...
        return func(self, proto, length, *args, **kwargs)
    return behold
```

##### Behold extraction procedure.

__NOTE__: this decorator works with class method `self._import_next_layer`, which has a *file-like* attribute names `self._file`.

### `beholder_ng`

```python
def beholder_ng(func):
    def behold(file, length, *args, **kwargs):
        ...
        return func(file, length, *args, **kwargs)
    return behold
```

##### Behold extraction procedure.

__NOTE__: positional argument `file` in `behold` must be a *file-like* object.

## Validations

 > described in [`src/utilities/validations.py`](https://github.com/JarryShaw/jspcap/tree/master/src/utilities/validations.py)

&emsp; `jspcap.utilities.validations` contains functions to validate arguments for functions and classes. It first appears in
[`jsntlib`](https://github.com/JarryShaw/jsntlib) as validators.

<a name="index-validations"> </a>

```python
type_check(*agrs, func=None)
```

|       NAME        |                 DESCRIPTION                 |
| :---------------: | :-----------------------------------------: |
|    `int_check`    |      Check if arguments are integrals.      |
|   `real_check`    |    Check if arguments are real numbers.     |
|  `complex_check`  |   Check if arguments are complex numbers.   |
|  `number_check`   |       Check if arguments are numbers.       |
|   `bytes_check`   |    Check if arguments are `bytes` type.     |
| `bytearray_check` |  Check if arguments are `bytearray` type.   |
|    `str_check`    |     Check if arguments are `str` type.      |
|   `bool_check`    |    Check if arguments are `bytes` type.     |
|   `list_check`    |     Check if arguments are `list` type.     |
|   `tuple_check`   |    Check if arguments are `tuple` type.     |
|    `io_check`     | Check if arguments are *file-like* object.  |
|   `info_check`    |   Check if arguments are Info instance.     |
|    `pkt_check`    |    Check if arguments are valid packets.    |
|   `frag_check`    |   Check if arguments are valid fragments.   |
| `_ip_frag_check`  | Check if arguments are valid IP fragments.  |
| `_tcp_frag_check` | Check if arguments are valid TCP fragments. |

&emsp; __EXCEPT__ `frag_check`, all validators take arbitrary positional arguments with one keyword argument named `func`, which takes a `str` type indicates the caller function of validation procedure.

<a name="notes-validations"> </a>

#### Nota Bene

```python
pkt_check(*args, func=None)
```

&emsp; `pkt_check` is the validator for `TraceFlow`. For more information on packet format, please refer to the documentation of [`TraceFlow`](https://github.com/JarryShaw/jspcap/tree/master/src/foundation#traceflow).

```python
frag_check(*args, protocol, func=None)
_ip_frag_check(*args, func=None)
_tcp_frag_check(*args, func=None)
```

&emsp; As for `frag_check`, `str` type keyword argument `protocol` indicates what protocol the fragment is reassembled for, which must be either `IP` (`IPv4` & `IPv6`) or `TCP`. Then, `_ip_frag_check` or `_tcp_frag_check` shall be called to validate arguments caller passed into. For more information on fragment format, please refer to the documentation of [`IP_Reassembly`](https://github.com/JarryShaw/jspcap/tree/master/src/reassembly#ip_reassembly) and [`TCP_Reassembly`](https://github.com/JarryShaw/jspcap/tree/master/src/reassembly#tcp_reassembly).

&nbsp;

## Exceptions

 > described in [`src/utilities/exceptions.py`](https://github.com/JarryShaw/jspcap/tree/master/src/utilities/exceptions.py)

&emsp; `jspcap.exceptions` refined built-in exceptions. Make it possible to show only user error stack information, when exception raised on user's operation.

### `BaseError`

```python
class BaseError(builtins.Exception)
```

##### Base error class of all kinds.

 - Data modules:
    * initialisation takes a special keyword argument `quiet` of `bool` type, referring if print no traceback information when exception raised
    * all other data modules inherited from `Exception`

 - Notes:

    * Turn off system-default traceback function by set `sys.tracebacklimit` to 0.

    * But bugs appear in Python 3.6, so we have to set `sys.tracebacklimit` to None.

        > this note is deprecated since Python fixed the problem above

    * In Python 2.7, `trace.print_stack(limit=None)` dose not support negative limit.

### Refined Exceptions

```python
class error(jspcap.utilities.exceptions.BaseError, builtins.Exception)
```

|           NAME           |            INHERIT FROM             |                     DESCRIPTION                     |
| :----------------------: | :---------------------------------: | :-------------------------------------------------: |
|       `DigitError`       |     `BaseError` / `TypeError`       |       The argument(s) must be (a) number(s).        |
|        `IntError`        |     `BaseError` / `TypeError`       |          The argument(s) must be integral.          |
|       `RealError`        |     `BaseError` / `TypeError`       |    The function is not defined for real number.     |
|      `ComplexError`      |     `BaseError` / `TypeError`       | The function is not defined for `complex` instance. |
|       `BytesError`       |     `BaseError` / `TypeError`       |        The argument(s) must be `bytes` type.        |
|     `BytearrayError`     |     `BaseError` / `TypeError`       |      The argument(s) must be `bytearray` type.      |
|       `BoolError`        |     `BaseError` / `TypeError`       |        The argument(s) must be `bool` type.         |
|      `StringError`       |     `BaseError` / `TypeError`       |         The argument(s) must be `str` type.         |
|       `DictError`        |     `BaseError` / `TypeError`       |        The argument(s) must be `dict` type.         |
|       `ListError`        |     `BaseError` / `TypeError`       |        The argument(s) must be `list` type.         |
|       `TupleError`       |     `BaseError` / `TypeError`       |        The argument(s) must be `tuple` type.        |
|     `IterableError`      |     `BaseError` / `TypeError`       |          The argument(s) must be iterable.          |
|     `CallableError`      |     `BaseError` / `TypeError`       |          The argument(s) must be callable.          |
|    `ProtocolUnbound`     |     `BaseError` / `TypeError`       |               Protocol slice unbound.               |
|       `IOObjError`       |     `BaseError` / `TypeError`       |     The argument(s) must be *file-like* object.     |
|       `InfoError`        |     `BaseError` / `TypeError`       |       The argument(s) must be Info instance.        |
|      `FormatError`       |   `BaseError` / `AttributeError`    |                 Unknown format(s).                  |
|    `UnsupportedCall`     |   `BaseError` / `AttributeError`    |       Unsupported function or property call.        |
|       `FileError`        |      `BaseError` / `IOError`        |                 Wrong file format.                  |
|      `FileNotFound`      | `BaseError` /  `FileNotFoundError`  |                   File not found.                   |
|    `ProtocolNotFound`    |     `BaseError` / `IndexError`      |         Protocol not found in `ProtoChain`.         |
|      `VersionError`      |     `BaseError` / `ValueError`      |                 Unknown IP version.                 |
|     `IndexNotFound`      |     `BaseError` / `ValueError`      |            Protocol not in `ProtoChain`.            |
|     `ProtocolError`      |     `BaseError` / `ValueError`      |              Invalid protocol format.               |
| `ProtocolNotImplemented` | `BaseError` / `NotImplementedError` |              Protocol not implemented.              |
|     `FragmentError`      |      `BaseError` / `KeyError`       |               Invalid fragment dict.                |
|      `PacketError`       |      `BaseError` / `KeyError`       |                Invalid packet dict.                 |
|      `StructError`       |    `BaseError` / `struct.error`     |                   Unpack failed.                    |
