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_bytes (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
+ """Parses a Kaitai Struct type"""
41
+ if isinstance (data , KaitaiStream ):
42
+ return cls (data )
43
+ elif isinstance (data , (str , Path , _IOBase )):
44
+ return cls .from_file (data , map )
45
+ elif isinstance (data , (bytes , bytearray )):
46
+ return cls .from_bytes (data )
47
+ else :
48
+ return cls .from_io (data )
49
+
50
+ @classmethod
51
+ def from_bytes (cls , buf ):
52
+ return cls .from_io (BytesIO (buf ))
17
53
18
- class KaitaiStruct (object ):
54
+ class KaitaiStruct (_KaitaiFromCtor ):
19
55
def __init__ (self , stream ):
20
56
self ._io = stream
21
57
@@ -28,26 +64,12 @@ def __exit__(self, *args, **kwargs):
28
64
def close (self ):
29
65
self ._io .close ()
30
66
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
67
@classmethod
46
68
def from_io (cls , io ):
47
69
return cls (KaitaiStream (io ))
48
70
49
71
50
- class KaitaiStream (object ):
72
+ class KaitaiStream (_KaitaiFromCtor ):
51
73
def __init__ (self , io ):
52
74
self ._io = io
53
75
self .align_to_byte ()
@@ -61,6 +83,10 @@ def __exit__(self, *args, **kwargs):
61
83
def close (self ):
62
84
self ._io .close ()
63
85
86
+ @classmethod
87
+ def from_io (cls , io ):
88
+ return cls (io )
89
+
64
90
# ========================================================================
65
91
# Stream positioning
66
92
# ========================================================================
0 commit comments