2
2
import sys
3
3
import struct
4
4
from io import open, BytesIO, SEEK_CUR, SEEK_END # noqa
5
+ from _io import _IOBase
6
+ import mmap
7
+ from pathlib import Path
5
8
6
9
PY2 = sys.version_info[0] == 2
7
10
14
17
#
15
18
__version__ = '0.9'
16
19
20
+ class _KaitaiFromCtor(object):
21
+ """Adds to class methods to construct it from ctor"""
22
+ @classmethod
23
+ def from_file(cls, file, map=True):
24
+ if isinstance(file, str):
25
+ return cls.from_file(Path(file), map)
26
+ elif isinstance(file, Path):
27
+ with file.open("rb") as f:
28
+ return cls.from_file(f, map)
29
+ elif isinstance(file, _IOBase):
30
+ if map:
31
+ with mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as buf:
32
+ return cls.from_io(buf)
33
+ else:
34
+ return cls.from_io(file)
35
+ else:
36
+ raise Exception("file argument must be either file path (either str or Path) or a file object")
37
+
38
+ @classmethod
39
+ def from_any(cls, data, map=True):
40
+ if isinstance(data, KaitaiStream):
41
+ return cls(data)
42
+ elif isinstance(data, (str, Path, _IOBase)):
43
+ return cls.from_file(data, map)
44
+ elif isinstance(data, (bytes, bytearray)):
45
+ return cls.from_bytes(data)
46
+ else:
47
+ return cls.from_io(data)
48
+
49
+ @classmethod
50
+ def from_bytes(cls, buf):
51
+ return cls.from_io(BytesIO(buf))
17
52
18
- class KaitaiStruct(object ):
53
+ class KaitaiStruct(_KaitaiFromCtor ):
19
54
def __init__(self, stream):
20
55
self._io = stream
21
56
@@ -28,26 +63,12 @@ def __exit__(self, *args, **kwargs):
28
63
def close(self):
29
64
self._io.close()
30
65
31
- @classmethod
32
- def from_file(cls, filename):
33
- f = open(filename, 'rb')
34
- try:
35
- return cls(KaitaiStream(f))
36
- except Exception:
37
- # close file descriptor, then reraise the exception
38
- f.close()
39
- raise
40
-
41
- @classmethod
42
- def from_bytes(cls, buf):
43
- return cls(KaitaiStream(BytesIO(buf)))
44
-
45
66
@classmethod
46
67
def from_io(cls, io):
47
68
return cls(KaitaiStream(io))
48
69
49
70
50
- class KaitaiStream(object ):
71
+ class KaitaiStream(_KaitaiFromCtor ):
51
72
def __init__(self, io):
52
73
self._io = io
53
74
self.align_to_byte()
@@ -61,6 +82,10 @@ def __exit__(self, *args, **kwargs):
61
82
def close(self):
62
83
self._io.close()
63
84
85
+ @classmethod
86
+ def from_io(cls, io):
87
+ return cls(io)
88
+
64
89
# ========================================================================
65
90
# Stream positioning
66
91
# ========================================================================
0 commit comments