archive/iso9660: use a single path buffer for Visit()

Avoid wasting 4 kB stack per directory level.
This commit is contained in:
Max Kellermann 2016-03-07 14:00:13 +01:00
parent c46fc4531b
commit de61c3b962

View File

@ -66,7 +66,8 @@ public:
return iso9660_iso_seek_read(iso, ptr, start, i_size); return iso9660_iso_seek_read(iso, ptr, start, i_size);
} }
void Visit(const char *path, ArchiveVisitor &visitor); void Visit(char *path, size_t length,
ArchiveVisitor &visitor);
virtual void Close() override { virtual void Close() override {
Unref(); Unref();
@ -84,11 +85,10 @@ static constexpr Domain iso9660_domain("iso9660");
/* archive open && listing routine */ /* archive open && listing routine */
inline void inline void
Iso9660ArchiveFile::Visit(const char *psz_path, ArchiveVisitor &visitor) Iso9660ArchiveFile::Visit(char *path, size_t length,
ArchiveVisitor &visitor)
{ {
char pathname[4096]; auto *entlist = iso9660_ifs_readdir(iso, path);
auto *entlist = iso9660_ifs_readdir (iso, psz_path);
if (!entlist) { if (!entlist) {
return; return;
} }
@ -101,15 +101,16 @@ Iso9660ArchiveFile::Visit(const char *psz_path, ArchiveVisitor &visitor)
if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
continue; continue;
strcpy(pathname, psz_path); size_t filename_length = strlen(filename);
strcat(pathname, filename); memcpy(path + length, filename, filename_length + 1);
size_t new_length = length + filename_length;
if (iso9660_stat_s::_STAT_DIR == statbuf->type ) { if (iso9660_stat_s::_STAT_DIR == statbuf->type ) {
strcat(pathname, "/"); memcpy(path + new_length, "/", 2);
Visit(pathname, visitor); Visit(path, new_length + 1, visitor);
} else { } else {
//remove leading / //remove leading /
visitor.VisitArchiveEntry(pathname + 1); visitor.VisitArchiveEntry(path + 1);
} }
} }
_cdio_list_free (entlist, true); _cdio_list_free (entlist, true);
@ -133,7 +134,8 @@ iso9660_archive_open(Path pathname, Error &error)
void void
Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor) Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor)
{ {
Visit("/", visitor); char path[4096] = "/";
Visit(path, 1, visitor);
} }
/* single archive handling */ /* single archive handling */