Skip to content

Commit 0323df6

Browse files
committed
merge seekable_stream_reader into stream_reader
1 parent 965f25d commit 0323df6

1 file changed

Lines changed: 11 additions & 33 deletions

File tree

libarchive/read.py

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,17 @@ def new_archive_read(format_name='all', filter_name='all', passphrase=None):
5757
@contextmanager
5858
def 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

Comments
 (0)