diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h index a56a4a292..463851caf 100644 --- a/libziparchive/include/ziparchive/zip_archive.h +++ b/libziparchive/include/ziparchive/zip_archive.h @@ -190,7 +190,8 @@ int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr, * archive and lower negative values on failure. */ int32_t Next(void* cookie, ZipEntry* data, std::string* name); -// TODO: remove this when everyone's moved over to std::string. +int32_t Next(void* cookie, ZipEntry* data, std::string_view* name); +// TODO: remove this when everyone's moved over to std::string/std::string_view. int32_t Next(void* cookie, ZipEntry* data, ZipString* name); /* diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index f4b6c74f8..e9662958f 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -748,10 +748,19 @@ int32_t FindEntry(const ZipArchiveHandle archive, const std::string_view entryNa } int32_t Next(void* cookie, ZipEntry* data, std::string* name) { + std::string_view sv; + int32_t result = Next(cookie, data, &sv); + if (result == 0 && name) { + *name = std::string(sv); + } + return result; +} + +int32_t Next(void* cookie, ZipEntry* data, std::string_view* name) { ZipString zs; int32_t result = Next(cookie, data, &zs); - if (result == 0) { - *name = std::string(reinterpret_cast(zs.name), zs.name_length); + if (result == 0 && name) { + *name = std::string_view(reinterpret_cast(zs.name), zs.name_length); } return result; } diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index b6ca9ecf5..8781ab79e 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -107,6 +107,26 @@ TEST(ziparchive, OpenDoNotAssumeFdOwnership) { close(fd); } +TEST(ziparchive, Iteration_std_string_view) { + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle)); + + void* iteration_cookie; + ASSERT_EQ(0, StartIteration(handle, &iteration_cookie)); + + ZipEntry data; + std::vector names; + std::string_view name; + while (Next(iteration_cookie, &data, &name) == 0) names.push_back(name); + + // Assert that the names are as expected. + std::vector expected_names{"a.txt", "b.txt", "b/", "b/c.txt", "b/d.txt"}; + std::sort(names.begin(), names.end()); + ASSERT_EQ(expected_names, names); + + CloseArchive(handle); +} + static void AssertIterationOrder(const std::string_view prefix, const std::string_view suffix, const std::vector& expected_names_sorted) { ZipArchiveHandle handle;