Skip to content

Commit a8d6562

Browse files
Avoid copying memory for zip file contents twice during extraction
1 parent ae2264d commit a8d6562

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

jbmc/src/java_bytecode/mz_zip_archive.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,17 @@ size_t mz_zip_archivet::get_num_files()
7373

7474
std::string mz_zip_archivet::get_filename(const size_t index)
7575
{
76-
const auto id=static_cast<mz_uint>(index);
77-
std::vector<char> buffer;
78-
buffer.resize(mz_zip_reader_get_filename(m_state.get(), id, nullptr, 0));
79-
mz_zip_reader_get_filename(m_state.get(), id, buffer.data(), buffer.size());
80-
// Buffer may contain junk returned after \0
81-
const auto null_char_it=std::find(buffer.cbegin(), buffer.cend(), '\0');
82-
return { buffer.cbegin(), null_char_it };
76+
const auto id = static_cast<mz_uint>(index);
77+
mz_uint name_size = mz_zip_reader_get_filename(m_state.get(), id, nullptr, 0);
78+
if(name_size == 0)
79+
return {}; // Failure
80+
// It is valid to directly write to a string's buffer (see C++11 standard,
81+
// basic_string general requirements [string.require], 21.4.1.5)
82+
std::string buffer(name_size, '\0');
83+
mz_zip_reader_get_filename(m_state.get(), id, &buffer[0], buffer.size());
84+
// Buffer contains trailing \0
85+
buffer.resize(name_size - 1);
86+
return buffer;
8387
}
8488

8589
std::string mz_zip_archivet::extract(const size_t index)
@@ -89,12 +93,13 @@ std::string mz_zip_archivet::extract(const size_t index)
8993
const mz_bool stat_ok=mz_zip_reader_file_stat(m_state.get(), id, &file_stat);
9094
if(stat_ok==MZ_TRUE)
9195
{
92-
std::vector<char> buffer(file_stat.m_uncomp_size);
93-
const mz_bool read_ok=mz_zip_reader_extract_to_mem(
94-
m_state.get(), id, buffer.data(), buffer.size(), 0);
95-
if(read_ok==MZ_TRUE)
96-
return { buffer.cbegin(), buffer.cend() };
96+
// It is valid to directly write to a string's buffer (see C++11 standard,
97+
// basic_string general requirements [string.require], 21.4.1.5)
98+
std::string buffer(file_stat.m_uncomp_size, '\0');
99+
const mz_bool read_ok = mz_zip_reader_extract_to_mem(
100+
m_state.get(), id, &buffer[0], buffer.size(), 0);
101+
if(read_ok == MZ_TRUE)
102+
return buffer;
97103
}
98104
throw std::runtime_error("Could not extract the file");
99105
}
100-

0 commit comments

Comments
 (0)