1+ from __future__ import annotations
2+
3+ from typing import TYPE_CHECKING , BinaryIO
4+
15from dissect .util .stream import AlignedStream
26from dissect .util .ts import wintimestamp
37
48from dissect .ole .c_ole import DECOLOR , SIGNATURE , SIGNATURE_BETA , STGTY , c_ole
59from dissect .ole .exceptions import Error , InvalidFileError , NotFoundError
610
11+ if TYPE_CHECKING :
12+ from collections .abc import Iterator
13+
714
815class OLE :
9- def __init__ (self , fh ):
16+ def __init__ (self , fh : BinaryIO ):
1017 self .fh = fh
1118 self .header = c_ole .StructuredStorageHeader (fh )
1219
@@ -37,7 +44,7 @@ def __init__(self, fh):
3744 self .root = self .directory (0 )
3845 self .ministream = self .root .open ()
3946
40- def get (self , path , root = None ):
47+ def get (self , path : str , root : DirectoryEntry | None = None ) -> DirectoryEntry :
4148 root = root or self .root
4249
4350 search_path = path .replace ("\\ " , "/" )
@@ -56,15 +63,15 @@ def get(self, path, root=None):
5663
5764 return node
5865
59- def directory (self , sid ) :
66+ def directory (self , sid : int ) -> DirectoryEntry :
6067 try :
6168 return self ._dircache [sid ]
6269 except KeyError :
6370 entry = DirectoryEntry (self , sid )
6471 self ._dircache [sid ] = entry
6572 return entry
6673
67- def fat (self , sect ) :
74+ def fat (self , sect : int ) -> int :
6875 idx , offset = divmod (sect , self .num_fat_entries )
6976
7077 try :
@@ -107,18 +114,18 @@ def fat(self, sect):
107114
108115 return table [offset ]
109116
110- def minifat (self , sect ) :
117+ def minifat (self , sect : int ) -> int :
111118 return self ._minifat [sect ]
112119
113- def chain (self , sect , size = None ):
120+ def chain (self , sect : int , size : int | None = None ) -> MiniChain :
114121 try :
115122 return self ._chaincache [sect ]
116123 except KeyError :
117124 chain = Chain (self , sect , size )
118125 self ._chaincache [sect ] = chain
119126 return chain
120127
121- def minichain (self , sect , size = None ):
128+ def minichain (self , sect : int , size : int | None = None ) -> MiniChain :
122129 try :
123130 return self ._minichaincache [sect ]
124131 except KeyError :
@@ -128,7 +135,7 @@ def minichain(self, sect, size=None):
128135
129136
130137class DirectoryEntry :
131- def __init__ (self , ole , sid ):
138+ def __init__ (self , ole : OLE , sid : int ):
132139 self .ole = ole
133140 self .sid = sid
134141
@@ -152,20 +159,20 @@ def __init__(self, ole, sid):
152159
153160 self ._dirlist = {}
154161
155- def __repr__ (self ):
156- return "<DirectoryEntry sid={} name={} type={} size=0x{:x}>" . format ( self . sid , self . name , self . type , self . size )
162+ def __repr__ (self ) -> str :
163+ return f "<DirectoryEntry sid={ self . sid } name={ self . name } type={ self . type } size=0x{ self . size :x} >"
157164
158- def open (self ):
165+ def open (self ) -> ChainStream :
159166 return self .chain .open ()
160167
161- def listdir (self ):
168+ def listdir (self ) -> dict [ str , DirectoryEntry ] :
162169 if not self ._dirlist :
163170 for entry in self .walk ():
164171 self ._dirlist [entry .name ] = entry
165172
166173 return self ._dirlist
167174
168- def walk (self ):
175+ def walk (self ) -> Iterator [ DirectoryEntry ] :
169176 if self .has_left_sibling :
170177 yield self .left_sibling
171178 yield from self .left_sibling .walk ()
@@ -181,77 +188,77 @@ def walk(self):
181188 yield from self .child .walk ()
182189
183190 @property
184- def child (self ):
191+ def child (self ) -> DirectoryEntry | None :
185192 if not self .has_child :
186193 return None
187194 return self .ole .directory (self .entry ._sidChild )
188195
189196 @property
190- def left_sibling (self ):
197+ def left_sibling (self ) -> DirectoryEntry | None :
191198 if not self .has_left_sibling :
192199 return None
193200 return self .ole .directory (self .entry ._sidLeftSib )
194201
195202 @property
196- def right_sibling (self ):
203+ def right_sibling (self ) -> DirectoryEntry | None :
197204 if not self .has_right_sibling :
198205 return None
199206 return self .ole .directory (self .entry ._sidRightSib )
200207
201208 @property
202- def has_child (self ):
209+ def has_child (self ) -> bool :
203210 return self .entry ._sidChild != 0xFFFFFFFF
204211
205212 @property
206- def has_left_sibling (self ):
213+ def has_left_sibling (self ) -> bool :
207214 return self .entry ._sidLeftSib != 0xFFFFFFFF
208215
209216 @property
210- def has_right_sibling (self ):
217+ def has_right_sibling (self ) -> bool :
211218 return self .entry ._sidRightSib != 0xFFFFFFFF
212219
213220 @property
214- def is_minifat (self ):
221+ def is_minifat (self ) -> bool :
215222 return self .is_stream and self .size < self .ole .mini_cutoff
216223
217224 @property
218- def is_red (self ):
225+ def is_red (self ) -> bool :
219226 return self .entry ._bflags == DECOLOR .DE_RED
220227
221228 @property
222- def is_black (self ):
229+ def is_black (self ) -> bool :
223230 return self .entry ._bflags == DECOLOR .DE_BLACK
224231
225232 @property
226- def is_valid (self ):
233+ def is_valid (self ) -> bool :
227234 return self .entry ._mse == STGTY .STGTY_INVALID
228235
229236 @property
230- def is_stream (self ):
237+ def is_stream (self ) -> bool :
231238 return self .entry ._mse == STGTY .STGTY_STREAM
232239
233240 @property
234- def is_storage (self ):
241+ def is_storage (self ) -> bool :
235242 return self .entry ._mse == STGTY .STGTY_STORAGE
236243
237244
238245class Chain :
239- def __init__ (self , ole , sect , size = None ):
246+ def __init__ (self , ole : OLE , sect : int , size : int | None = None ):
240247 self .ole = ole
241248 self .sect = sect
242249 self .size = size
243250 self .chain = [sect ]
244251 self .ended = False
245252
246- def __len__ (self ):
253+ def __len__ (self ) -> int :
247254 self .fill ()
248255 return len (self .chain )
249256
250- def __iter__ (self ):
257+ def __iter__ (self ) -> Iterator [ int ] :
251258 self .fill ()
252259 return iter (self .chain )
253260
254- def __getitem__ (self , i ) :
261+ def __getitem__ (self , i : int ) -> int :
255262 cur = len (self .chain )
256263 tail = self .chain [- 1 ]
257264
@@ -271,10 +278,10 @@ def __getitem__(self, i):
271278
272279 return self .chain [i ]
273280
274- def open (self ):
281+ def open (self ) -> ChainStream :
275282 return ChainStream (self .ole .fh , self , self .ole .sector_size , offset = self .ole .sector_size )
276283
277- def fill (self ):
284+ def fill (self ) -> None :
278285 if self .ended :
279286 return
280287
@@ -283,28 +290,28 @@ def fill(self):
283290 except IndexError :
284291 pass
285292
286- def _lookup (self , sect ) :
293+ def _lookup (self , sect : int ) -> int :
287294 return self .ole .fat (sect )
288295
289296
290297class MiniChain (Chain ):
291- def open (self ):
298+ def open (self ) -> ChainStream :
292299 return ChainStream (self .ole .ministream , self , self .ole .mini_sector_size )
293300
294- def _lookup (self , sect ) :
301+ def _lookup (self , sect : int ) -> int :
295302 return self .ole .minifat (sect )
296303
297304
298305class ChainStream (AlignedStream ):
299- def __init__ (self , stream , chain , sector_size , offset = 0 ):
306+ def __init__ (self , stream : BinaryIO , chain : Chain , sector_size : int , offset : int = 0 ):
300307 self ._fh = stream
301308 self .chain = chain
302309 self .sector_size = sector_size
303310 self .offset = offset
304311
305312 super ().__init__ (chain .size )
306313
307- def _read (self , offset , length ) :
314+ def _read (self , offset : int , length : int ) -> bytes :
308315 r = []
309316
310317 if not self .size and length == - 1 :
@@ -321,10 +328,7 @@ def _read(self, offset, length):
321328 except IndexError :
322329 break
323330
324- if self .size :
325- sectread = min (self .size - offset , sector_size )
326- else :
327- sectread = sector_size
331+ sectread = min (self .size - offset , sector_size ) if self .size else sector_size
328332 fileoffset = self .offset + sectnum * sector_size
329333
330334 self ._fh .seek (fileoffset )
0 commit comments