summaryrefslogtreecommitdiff
path: root/qutebrowser/misc/binparsing.py
blob: 81e2e6dbb77c29cc00e62d921b0fd30c039420ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# SPDX-FileCopyrightText: Florian Bruhin (The-Compiler) <mail@qutebrowser.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later

"""Utilities for parsing binary files.

Used by elf.py as well as pakjoy.py.
"""

import struct
from typing import Any, IO, Tuple


class ParseError(Exception):

    """Raised when the file can't be parsed."""


def unpack(fmt: str, fobj: IO[bytes]) -> Tuple[Any, ...]:
    """Unpack the given struct format from the given file."""
    size = struct.calcsize(fmt)
    data = safe_read(fobj, size)

    try:
        return struct.unpack(fmt, data)
    except struct.error as e:
        raise ParseError(e)


def safe_read(fobj: IO[bytes], size: int) -> bytes:
    """Read from a file, handling possible exceptions."""
    try:
        return fobj.read(size)
    except (OSError, OverflowError) as e:
        raise ParseError(e)


def safe_seek(fobj: IO[bytes], pos: int) -> None:
    """Seek in a file, handling possible exceptions."""
    try:
        fobj.seek(pos)
    except (OSError, OverflowError) as e:
        raise ParseError(e)