Skip to content

Commit d72dc7c

Browse files
committed
enable keeping all the entries of an archive in memory
fixes #43, fixes #104
1 parent 98c14d2 commit d72dc7c

3 files changed

Lines changed: 65 additions & 64 deletions

File tree

libarchive/entry.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ class ArchiveEntry:
2424

2525
__slots__ = ('_archive_p', '_entry_p')
2626

27-
def __init__(self, archive_p, entry_p):
27+
def __init__(self, archive_p):
2828
self._archive_p = archive_p
29-
self._entry_p = entry_p
29+
self._entry_p = ffi.entry_new()
30+
31+
def __del__(self):
32+
ffi.entry_free(self._entry_p)
3033

3134
def __str__(self):
3235
return self.pathname

libarchive/read.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
ARCHIVE_EOF, OPEN_CALLBACK, READ_CALLBACK, CLOSE_CALLBACK, SEEK_CALLBACK,
88
NO_OPEN_CB, NO_CLOSE_CB, page_size,
99
)
10-
from .entry import ArchiveEntry, new_archive_entry
10+
from .entry import ArchiveEntry
1111

1212

1313
class ArchiveRead:
@@ -20,13 +20,12 @@ def __iter__(self):
2020
"""
2121
archive_p = self._pointer
2222
read_next_header2 = ffi.read_next_header2
23-
with new_archive_entry() as entry_p:
24-
entry = ArchiveEntry(archive_p, entry_p)
25-
while 1:
26-
r = read_next_header2(archive_p, entry_p)
27-
if r == ARCHIVE_EOF:
28-
return
29-
yield entry
23+
while 1:
24+
entry = ArchiveEntry(archive_p)
25+
r = read_next_header2(archive_p, entry._entry_p)
26+
if r == ARCHIVE_EOF:
27+
return
28+
yield entry
3029

3130

3231
@contextmanager

libarchive/write.py

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import warnings
44

55
from . import ffi
6-
from .entry import ArchiveEntry, new_archive_entry
6+
from .entry import ArchiveEntry
77
from .ffi import (
88
OPEN_CALLBACK, WRITE_CALLBACK, CLOSE_CALLBACK, NO_OPEN_CB, NO_CLOSE_CB,
99
REGULAR_FILE, DEFAULT_UNIX_PERMISSION, ARCHIVE_EOF,
@@ -53,26 +53,26 @@ def add_files(self, *paths, **kw):
5353
if block_size <= 0:
5454
block_size = 10240 # pragma: no cover
5555

56-
with new_archive_entry() as entry_p:
57-
entry = ArchiveEntry(None, entry_p)
58-
for path in paths:
59-
with new_archive_read_disk(path, **kw) as read_p:
60-
while 1:
61-
r = read_next_header2(read_p, entry_p)
62-
if r == ARCHIVE_EOF:
63-
break
64-
entry.pathname = entry.pathname.lstrip('/')
65-
read_disk_descend(read_p)
66-
write_header(write_p, entry_p)
67-
if entry.isreg:
68-
with open(entry_sourcepath(entry_p), 'rb') as f:
69-
while 1:
70-
data = f.read(block_size)
71-
if not data:
72-
break
73-
write_data(write_p, data, len(data))
74-
write_finish_entry(write_p)
75-
entry_clear(entry_p)
56+
entry = ArchiveEntry(None)
57+
entry_p = entry._entry_p
58+
for path in paths:
59+
with new_archive_read_disk(path, **kw) as read_p:
60+
while 1:
61+
r = read_next_header2(read_p, entry_p)
62+
if r == ARCHIVE_EOF:
63+
break
64+
entry.pathname = entry.pathname.lstrip('/')
65+
read_disk_descend(read_p)
66+
write_header(write_p, entry_p)
67+
if entry.isreg:
68+
with open(entry_sourcepath(entry_p), 'rb') as f:
69+
while 1:
70+
data = f.read(block_size)
71+
if not data:
72+
break
73+
write_data(write_p, data, len(data))
74+
write_finish_entry(write_p)
75+
entry_clear(entry_p)
7676

7777
def add_file_from_memory(
7878
self, entry_path, entry_size, entry_data,
@@ -110,39 +110,38 @@ def add_file_from_memory(
110110
"entry_data: expected bytes, got %r" % type(entry_data)
111111
)
112112

113-
with new_archive_entry() as archive_entry_pointer:
114-
archive_entry = ArchiveEntry(None, archive_entry_pointer)
115-
116-
archive_entry.pathname = entry_path
117-
entry_set_size(archive_entry_pointer, entry_size)
118-
entry_set_filetype(archive_entry_pointer, filetype)
119-
entry_set_perm(archive_entry_pointer, permission)
120-
121-
if atime is not None:
122-
if not isinstance(atime, tuple):
123-
atime = (atime, 0)
124-
archive_entry.set_atime(*atime)
125-
if mtime is not None:
126-
if not isinstance(mtime, tuple):
127-
mtime = (mtime, 0)
128-
archive_entry.set_mtime(*mtime)
129-
if ctime is not None:
130-
if not isinstance(ctime, tuple):
131-
ctime = (ctime, 0)
132-
archive_entry.set_ctime(*ctime)
133-
if birthtime is not None:
134-
if not isinstance(birthtime, tuple):
135-
birthtime = (birthtime, 0)
136-
archive_entry.set_birthtime(*birthtime)
137-
write_header(archive_pointer, archive_entry_pointer)
138-
139-
for chunk in entry_data:
140-
if not chunk:
141-
break
142-
write_data(archive_pointer, chunk, len(chunk))
143-
144-
write_finish_entry(archive_pointer)
145-
entry_clear(archive_entry_pointer)
113+
archive_entry = ArchiveEntry(None)
114+
archive_entry_pointer = archive_entry._entry_p
115+
116+
archive_entry.pathname = entry_path
117+
entry_set_size(archive_entry_pointer, entry_size)
118+
entry_set_filetype(archive_entry_pointer, filetype)
119+
entry_set_perm(archive_entry_pointer, permission)
120+
121+
if atime is not None:
122+
if not isinstance(atime, tuple):
123+
atime = (atime, 0)
124+
archive_entry.set_atime(*atime)
125+
if mtime is not None:
126+
if not isinstance(mtime, tuple):
127+
mtime = (mtime, 0)
128+
archive_entry.set_mtime(*mtime)
129+
if ctime is not None:
130+
if not isinstance(ctime, tuple):
131+
ctime = (ctime, 0)
132+
archive_entry.set_ctime(*ctime)
133+
if birthtime is not None:
134+
if not isinstance(birthtime, tuple):
135+
birthtime = (birthtime, 0)
136+
archive_entry.set_birthtime(*birthtime)
137+
write_header(archive_pointer, archive_entry_pointer)
138+
139+
for chunk in entry_data:
140+
if not chunk:
141+
break
142+
write_data(archive_pointer, chunk, len(chunk))
143+
144+
write_finish_entry(archive_pointer)
146145

147146

148147
@contextmanager

0 commit comments

Comments
 (0)