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