@@ -57,15 +57,17 @@ def new_archive_read(format_name='all', filter_name='all', passphrase=None):
5757@contextmanager
5858def custom_reader (
5959 read_func , format_name = 'all' , filter_name = 'all' ,
60- open_func = VOID_CB , close_func = VOID_CB , block_size = page_size ,
61- archive_read_class = ArchiveRead , passphrase = None ,
60+ open_func = VOID_CB , seek_func = None , close_func = VOID_CB ,
61+ block_size = page_size , archive_read_class = ArchiveRead , passphrase = None ,
6262):
6363 """Read an archive using a custom function.
6464 """
6565 open_cb = OPEN_CALLBACK (open_func )
6666 read_cb = READ_CALLBACK (read_func )
6767 close_cb = CLOSE_CALLBACK (close_func )
6868 with new_archive_read (format_name , filter_name , passphrase ) as archive_p :
69+ if seek_func :
70+ ffi .read_set_seek_callback (archive_p , SEEK_CALLBACK (seek_func ))
6971 ffi .read_open (archive_p , None , open_cb , read_cb , close_cb )
7072 yield archive_read_class (archive_p )
7173
@@ -117,36 +119,9 @@ def stream_reader(
117119 """Read an archive from a stream.
118120
119121 The `stream` object must support the standard `readinto` method.
120- """
121- buf = create_string_buffer (block_size )
122- buf_p = cast (buf , c_void_p )
123-
124- def read_func (archive_p , context , ptrptr ):
125- # readinto the buffer, returns number of bytes read
126- length = stream .readinto (buf )
127- # write the address of the buffer into the pointer
128- ptrptr = cast (ptrptr , POINTER (c_void_p ))
129- ptrptr [0 ] = buf_p
130- # tell libarchive how much data was written into the buffer
131- return length
132122
133- open_cb = OPEN_CALLBACK (VOID_CB )
134- read_cb = READ_CALLBACK (read_func )
135- close_cb = CLOSE_CALLBACK (VOID_CB )
136- with new_archive_read (format_name , filter_name , passphrase ) as archive_p :
137- ffi .read_open (archive_p , None , open_cb , read_cb , close_cb )
138- yield ArchiveRead (archive_p )
139-
140-
141- @contextmanager
142- def seekable_stream_reader (
143- stream , format_name = 'all' , filter_name = 'all' , block_size = page_size ,
144- passphrase = None ,
145- ):
146- """Read an archive from a seekable stream.
147-
148- The `stream` object must support the standard `readinto`, 'seek' and
149- 'tell' methods.
123+ If `stream.seekable()` returns `True`, then an appropriate seek callback is
124+ passed to libarchive.
150125 """
151126 buf = create_string_buffer (block_size )
152127 buf_p = cast (buf , c_void_p )
@@ -167,9 +142,12 @@ def seek_func(archive_p, context, offset, whence):
167142
168143 open_cb = OPEN_CALLBACK (VOID_CB )
169144 read_cb = READ_CALLBACK (read_func )
170- seek_cb = SEEK_CALLBACK (seek_func )
171145 close_cb = CLOSE_CALLBACK (VOID_CB )
172146 with new_archive_read (format_name , filter_name , passphrase ) as archive_p :
173- ffi .read_set_seek_callback (archive_p , seek_cb )
147+ if stream .seekable ():
148+ ffi .read_set_seek_callback (archive_p , SEEK_CALLBACK (seek_func ))
174149 ffi .read_open (archive_p , None , open_cb , read_cb , close_cb )
175150 yield ArchiveRead (archive_p )
151+
152+
153+ seekable_stream_reader = stream_reader
0 commit comments