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