Skip to content

Commit 7525a0c

Browse files
authored
load extra formats and filters when they're requested (#95)
1 parent 401a7e1 commit 7525a0c

3 files changed

Lines changed: 65 additions & 21 deletions

File tree

libarchive/ffi.py

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,50 @@ def ffi(name, argtypes, restype, errcheck=None):
101101
return f
102102

103103

104+
def get_read_format_function(format_name):
105+
function_name = 'read_support_format_' + format_name
106+
func = globals().get(function_name)
107+
if func:
108+
return func
109+
try:
110+
return ffi(function_name, [c_archive_p], c_int, check_int)
111+
except AttributeError:
112+
raise ValueError('the read format %r is not available' % format_name)
113+
114+
115+
def get_read_filter_function(filter_name):
116+
function_name = 'read_support_filter_' + filter_name
117+
func = globals().get(function_name)
118+
if func:
119+
return func
120+
try:
121+
return ffi(function_name, [c_archive_p], c_int, check_int)
122+
except AttributeError:
123+
raise ValueError('the read filter %r is not available' % filter_name)
124+
125+
126+
def get_write_format_function(format_name):
127+
function_name = 'write_set_format_' + format_name
128+
func = globals().get(function_name)
129+
if func:
130+
return func
131+
try:
132+
return ffi(function_name, [c_archive_p], c_int, check_int)
133+
except AttributeError:
134+
raise ValueError('the write format %r is not available' % format_name)
135+
136+
137+
def get_write_filter_function(filter_name):
138+
function_name = 'write_add_filter_' + filter_name
139+
func = globals().get(function_name)
140+
if func:
141+
return func
142+
try:
143+
return ffi(function_name, [c_archive_p], c_int, check_int)
144+
except AttributeError:
145+
raise ValueError('the write filter %r is not available' % filter_name)
146+
147+
104148
# FFI declarations
105149

106150
# archive_util
@@ -160,9 +204,9 @@ def ffi(name, argtypes, restype, errcheck=None):
160204
))
161205
for f_name in list(READ_FORMATS):
162206
try:
163-
ffi('read_support_format_'+f_name, [c_archive_p], c_int, check_int)
164-
except AttributeError: # pragma: no cover
165-
logger.info('read format "%s" is not supported' % f_name)
207+
get_read_format_function(f_name)
208+
except ValueError as e: # pragma: no cover
209+
logger.info(str(e))
166210
READ_FORMATS.remove(f_name)
167211

168212
READ_FILTERS = set((
@@ -171,9 +215,9 @@ def ffi(name, argtypes, restype, errcheck=None):
171215
))
172216
for f_name in list(READ_FILTERS):
173217
try:
174-
ffi('read_support_filter_'+f_name, [c_archive_p], c_int, check_int)
175-
except AttributeError: # pragma: no cover
176-
logger.info('read filter "%s" is not supported' % f_name)
218+
get_read_filter_function(f_name)
219+
except ValueError as e: # pragma: no cover
220+
logger.info(str(e))
177221
READ_FILTERS.remove(f_name)
178222

179223
ffi('read_open',
@@ -222,9 +266,9 @@ def ffi(name, argtypes, restype, errcheck=None):
222266
))
223267
for f_name in list(WRITE_FORMATS):
224268
try:
225-
ffi('write_set_format_'+f_name, [c_archive_p], c_int, check_int)
226-
except AttributeError: # pragma: no cover
227-
logger.info('write format "%s" is not supported' % f_name)
269+
get_write_format_function(f_name)
270+
except ValueError as e: # pragma: no cover
271+
logger.info(str(e))
228272
WRITE_FORMATS.remove(f_name)
229273

230274
WRITE_FILTERS = set((
@@ -233,9 +277,9 @@ def ffi(name, argtypes, restype, errcheck=None):
233277
))
234278
for f_name in list(WRITE_FILTERS):
235279
try:
236-
ffi('write_add_filter_'+f_name, [c_archive_p], c_int, check_int)
237-
except AttributeError: # pragma: no cover
238-
logger.info('write filter "%s" is not supported' % f_name)
280+
get_write_filter_function(f_name)
281+
except ValueError as e: # pragma: no cover
282+
logger.info(str(e))
239283
WRITE_FILTERS.remove(f_name)
240284

241285
ffi('write_open',

libarchive/read.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ def new_archive_read(format_name='all', filter_name='all'):
3636
Returns a pointer if successful. Raises ArchiveError on error.
3737
"""
3838
archive_p = ffi.read_new()
39-
getattr(ffi, 'read_support_filter_'+filter_name)(archive_p)
40-
getattr(ffi, 'read_support_format_'+format_name)(archive_p)
4139
try:
40+
ffi.get_read_filter_function(filter_name)(archive_p)
41+
ffi.get_read_format_function(format_name)(archive_p)
4242
yield archive_p
4343
finally:
4444
ffi.read_free(archive_p)

libarchive/write.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,14 @@ def add_file_from_memory(
149149
@contextmanager
150150
def new_archive_write(format_name, filter_name=None, options=''):
151151
archive_p = ffi.write_new()
152-
getattr(ffi, 'write_set_format_'+format_name)(archive_p)
153-
if filter_name:
154-
getattr(ffi, 'write_add_filter_'+filter_name)(archive_p)
155-
if options:
156-
if not isinstance(options, bytes):
157-
options = options.encode('utf-8')
158-
ffi.write_set_options(archive_p, options)
159152
try:
153+
ffi.get_write_format_function(format_name)(archive_p)
154+
if filter_name:
155+
ffi.get_write_filter_function(filter_name)(archive_p)
156+
if options:
157+
if not isinstance(options, bytes):
158+
options = options.encode('utf-8')
159+
ffi.write_set_options(archive_p, options)
160160
yield archive_p
161161
ffi.write_close(archive_p)
162162
ffi.write_free(archive_p)

0 commit comments

Comments
 (0)