33import struct
44from struct import unpack
55from io import BytesIO # noqa
6+ from _io import _IOBase
7+ import mmap
8+ from pathlib import Path
69
710PY2 = sys .version_info [0 ] == 2
811
1518#
1619__version__ = '0.8'
1720
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 ))
1854
19- class KaitaiStruct (object ):
55+ class KaitaiStruct (_KaitaiFromCtor ):
2056 def __init__ (self , stream ):
2157 self ._io = stream
2258
@@ -29,26 +65,12 @@ def __exit__(self, *args, **kwargs):
2965 def close (self ):
3066 self ._io .close ()
3167
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-
4668 @classmethod
4769 def from_io (cls , io ):
4870 return cls (KaitaiStream (io ))
4971
5072
51- class KaitaiStream (object ):
73+ class KaitaiStream (_KaitaiFromCtor ):
5274 def __init__ (self , io ):
5375 self ._io = io
5476 self .align_to_byte ()
@@ -62,6 +84,10 @@ def __exit__(self, *args, **kwargs):
6284 def close (self ):
6385 self ._io .close ()
6486
87+ @classmethod
88+ def from_io (cls , io ):
89+ return cls (io )
90+
6591 # ========================================================================
6692 # Stream positioning
6793 # ========================================================================
0 commit comments