mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
unzip: Add option to list files of an archive
This commit is contained in:
parent
a9a62ad8c9
commit
dc65a2f2b8
Notes:
sideshowbarker
2024-07-17 09:39:38 +09:00
Author: https://github.com/romch007 Commit: https://github.com/SerenityOS/serenity/commit/dc65a2f2b8 Pull-request: https://github.com/SerenityOS/serenity/pull/19014 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/LucasChollet Reviewed-by: https://github.com/awesomekling
3 changed files with 28 additions and 3 deletions
|
@ -75,7 +75,7 @@ Optional<Zip> Zip::try_create(ReadonlyBytes buffer)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<bool> Zip::for_each_member(Function<IterationDecision(ZipMember const&)> callback)
|
ErrorOr<bool> Zip::for_each_member(Function<ErrorOr<IterationDecision>(ZipMember const&)> callback)
|
||||||
{
|
{
|
||||||
size_t member_offset = m_members_start_offset;
|
size_t member_offset = m_members_start_offset;
|
||||||
for (size_t i = 0; i < m_member_count; i++) {
|
for (size_t i = 0; i < m_member_count; i++) {
|
||||||
|
@ -94,7 +94,7 @@ ErrorOr<bool> Zip::for_each_member(Function<IterationDecision(ZipMember const&)>
|
||||||
member.modification_date = central_directory_record.modification_date;
|
member.modification_date = central_directory_record.modification_date;
|
||||||
member.is_directory = central_directory_record.external_attributes & zip_directory_external_attribute || member.name.bytes_as_string_view().ends_with('/'); // FIXME: better directory detection
|
member.is_directory = central_directory_record.external_attributes & zip_directory_external_attribute || member.name.bytes_as_string_view().ends_with('/'); // FIXME: better directory detection
|
||||||
|
|
||||||
if (callback(member) == IterationDecision::Break)
|
if (TRY(callback(member)) == IterationDecision::Break)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
member_offset += central_directory_record.size();
|
member_offset += central_directory_record.size();
|
||||||
|
|
|
@ -253,7 +253,7 @@ struct ZipMember {
|
||||||
class Zip {
|
class Zip {
|
||||||
public:
|
public:
|
||||||
static Optional<Zip> try_create(ReadonlyBytes buffer);
|
static Optional<Zip> try_create(ReadonlyBytes buffer);
|
||||||
ErrorOr<bool> for_each_member(Function<IterationDecision(ZipMember const&)>);
|
ErrorOr<bool> for_each_member(Function<ErrorOr<IterationDecision>(ZipMember const&)>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool find_end_of_central_directory_offset(ReadonlyBytes, size_t& offset);
|
static bool find_end_of_central_directory_offset(ReadonlyBytes, size_t& offset);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <LibArchive/Zip.h>
|
#include <LibArchive/Zip.h>
|
||||||
#include <LibCompress/Deflate.h>
|
#include <LibCompress/Deflate.h>
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
|
#include <LibCore/DateTime.h>
|
||||||
#include <LibCore/Directory.h>
|
#include <LibCore/Directory.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/MappedFile.h>
|
#include <LibCore/MappedFile.h>
|
||||||
|
@ -104,10 +105,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
StringView zip_file_path;
|
StringView zip_file_path;
|
||||||
bool quiet { false };
|
bool quiet { false };
|
||||||
|
bool list_files { false };
|
||||||
StringView output_directory_path;
|
StringView output_directory_path;
|
||||||
Vector<StringView> file_filters;
|
Vector<StringView> file_filters;
|
||||||
|
|
||||||
Core::ArgsParser args_parser;
|
Core::ArgsParser args_parser;
|
||||||
|
args_parser.add_option(list_files, "Only list files in the archive", "list", 'l');
|
||||||
args_parser.add_option(output_directory_path, "Directory to receive the archive content", "output-directory", 'd', "path");
|
args_parser.add_option(output_directory_path, "Directory to receive the archive content", "output-directory", 'd', "path");
|
||||||
args_parser.add_option(quiet, "Be less verbose", "quiet", 'q');
|
args_parser.add_option(quiet, "Be less verbose", "quiet", 'q');
|
||||||
args_parser.add_positional_argument(zip_file_path, "File to unzip", "path", Core::ArgsParser::Required::Yes);
|
args_parser.add_positional_argument(zip_file_path, "File to unzip", "path", Core::ArgsParser::Required::Yes);
|
||||||
|
@ -140,6 +143,28 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
TRY(Core::System::chdir(output_directory_path));
|
TRY(Core::System::chdir(output_directory_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (list_files) {
|
||||||
|
outln(" Length Date Time Name");
|
||||||
|
outln("--------- ---------- -------- ----");
|
||||||
|
u32 members_count = 0;
|
||||||
|
u64 total_size = 0;
|
||||||
|
TRY(zip_file->for_each_member([&](auto zip_member) -> ErrorOr<IterationDecision> {
|
||||||
|
members_count++;
|
||||||
|
|
||||||
|
auto time = time_from_packed_dos(zip_member.modification_date, zip_member.modification_time);
|
||||||
|
auto time_str = TRY(Core::DateTime::from_timestamp(time.seconds_since_epoch()).to_string());
|
||||||
|
|
||||||
|
total_size += zip_member.uncompressed_size;
|
||||||
|
|
||||||
|
outln("{:>9} {} {}", zip_member.uncompressed_size, time_str, zip_member.name);
|
||||||
|
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
}));
|
||||||
|
outln("--------- ----");
|
||||||
|
outln("{:>9} {} files", total_size, members_count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<Archive::ZipMember> zip_directories;
|
Vector<Archive::ZipMember> zip_directories;
|
||||||
|
|
||||||
auto success = TRY(zip_file->for_each_member([&](auto zip_member) {
|
auto success = TRY(zip_file->for_each_member([&](auto zip_member) {
|
||||||
|
|
Loading…
Reference in a new issue