22import sys
33import struct
44from io import open , BytesIO , SEEK_CUR , SEEK_END # noqa
5+ from _io import _IOBase
6+ import mmap
7+ from pathlib import Path
58
69PY2 = sys .version_info [0 ] == 2
710
1417#
1518__version__ = '0.9'
1619
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 ))
1752
18- class KaitaiStruct (object ):
53+ class KaitaiStruct (_KaitaiFromCtor ):
1954 def __init__ (self , stream ):
2055 self ._io = stream
2156
@@ -28,26 +63,12 @@ def __exit__(self, *args, **kwargs):
2863 def close (self ):
2964 self ._io .close ()
3065
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-
4566 @classmethod
4667 def from_io (cls , io ):
4768 return cls (KaitaiStream (io ))
4869
4970
50- class KaitaiStream (object ):
71+ class KaitaiStream (_KaitaiFromCtor ):
5172 def __init__ (self , io ):
5273 self ._io = io
5374 self .align_to_byte ()
@@ -61,6 +82,10 @@ def __exit__(self, *args, **kwargs):
6182 def close (self ):
6283 self ._io .close ()
6384
85+ @classmethod
86+ def from_io (cls , io ):
87+ return cls (io )
88+
6489 # ========================================================================
6590 # Stream positioning
6691 # ========================================================================
0 commit comments