1- # Copyright 2015-2022 the openage authors. See copying.md for legal info.
1+ # Copyright 2015-2024 the openage authors. See copying.md for legal info.
22
33"""
44Provides Filecollection, a utility class for combining multiple file-like
55objects to a FSLikeObject.
66"""
7+ from __future__ import annotations
8+ import typing
79
810from collections import OrderedDict
911from io import UnsupportedOperation
1214from .abstract import FSLikeObject
1315from .path import Path
1416
17+ if typing .TYPE_CHECKING :
18+ from openage .util .filelike .stream import StreamFragment
19+
1520
1621class FileCollection (FSLikeObject ):
1722 """
@@ -59,14 +64,12 @@ def get_direntries(self, parts=None, create: bool = False) -> tuple[OrderedDict,
5964
6065 return entries
6166
62- def add_fileentry (self , parts , fileentry ):
67+ def add_fileentry (self , parts , fileentry : FileEntry ):
6368 """
6469 Adds a file entry (and parent directory entries, if needed).
6570
6671 This method should not be called directly; instead, use the
6772 add_file method of Path objects that were obtained from this.
68-
69- fileentry must be open_r, open_w, size, mtime.
7073 """
7174 if not parts :
7275 raise IsADirectoryError ("FileCollection.root is a directory" )
@@ -79,11 +82,9 @@ def add_fileentry(self, parts, fileentry):
7982
8083 entries [0 ][name ] = fileentry
8184
82- def get_fileentry (self , parts ):
85+ def get_fileentry (self , parts ) -> FileEntry :
8386 """
8487 Gets a file entry. Helper method for internal use.
85-
86- Returns open_r, open_w, size, mtime
8788 """
8889 if not parts :
8990 raise IsADirectoryError (
@@ -101,45 +102,45 @@ def get_fileentry(self, parts):
101102
102103 return entries [0 ][name ]
103104
104- def open_r (self , parts ) -> None :
105- open_r , _ , _ , _ = self .get_fileentry (parts )
105+ def open_r (self , parts : list [bytes ]) -> StreamFragment :
106+ entry = self .get_fileentry (parts )
107+
108+ open_r = entry .open_r ()
106109
107110 if open_r is None :
108111 raise UnsupportedOperation (
109112 "not readable: " +
110113 b"/" .join (parts ).decode (errors = 'replace' ))
111114
112- return open_r ()
115+ return open_r
116+
117+ def open_w (self , parts : list [bytes ]):
118+ entry = self .get_fileentry (parts )
113119
114- def open_w (self , parts ) -> None :
115- _ , open_w , _ , _ = self .get_fileentry (parts )
120+ open_w = entry .open_w ()
116121
117122 if open_w is None :
118123 raise UnsupportedOperation (
119124 "not writable: " +
120125 b"/" .join (parts ).decode (errors = 'replace' ))
121126
127+ return open_w
128+
122129 def list (self , parts ):
123130 fileentries , subdirs = self .get_direntries (parts )
124131
125132 yield from subdirs
126133 yield from fileentries
127134
128135 def filesize (self , parts ) -> int :
129- _ , _ , filesize , _ = self .get_fileentry (parts )
136+ entry = self .get_fileentry (parts )
130137
131- if filesize is None :
132- return None
133-
134- return filesize ()
138+ return entry .size ()
135139
136140 def mtime (self , parts ) -> float :
137- _ , _ , _ , mtime = self .get_fileentry (parts )
138-
139- if mtime is None :
140- return None
141+ entry = self .get_fileentry (parts )
141142
142- return mtime ()
143+ return entry . mtime ()
143144
144145 def mkdirs (self , parts ) -> None :
145146 self .get_direntries (parts , create = True )
@@ -248,3 +249,34 @@ def add_file_from_path(self, path: Path) -> None:
248249 open_w = None
249250
250251 self .add_file (path .open_r , open_w , path .filesize , path .mtime )
252+
253+
254+ class FileEntry :
255+ """
256+ Entry in a file collection archive.
257+ """
258+ # pylint: disable=no-self-use
259+
260+ def open_r (self ) -> StreamFragment :
261+ """
262+ Returns a file-like object for reading.
263+ """
264+ raise UnsupportedOperation ("FileEntry.open_r" )
265+
266+ def open_w (self ):
267+ """
268+ Returns a file-like object for writing.
269+ """
270+ raise UnsupportedOperation ("FileEntry.open_w" )
271+
272+ def size (self ) -> int :
273+ """
274+ Returns the size of the entr<.
275+ """
276+ raise UnsupportedOperation ("FileEntry.size" )
277+
278+ def mtime (self ) -> float :
279+ """
280+ Returns the modification time of the entry.
281+ """
282+ raise UnsupportedOperation ("FileEntry.mtime" )
0 commit comments