From 96efa81dc64f346bbf019f127dbab915479748fe Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Thu, 16 Nov 2023 14:05:13 +0100 Subject: [PATCH] Utilities/wc: Seek the input file(s) if only -c is passed If the user only wants to get the byte count of a set of files, then for each file we can simply seek it to get the byte count instead of iterating over all the bytes. --- Userland/Utilities/wc.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Userland/Utilities/wc.cpp b/Userland/Utilities/wc.cpp index 21f74502f59..951963dd5ad 100644 --- a/Userland/Utilities/wc.cpp +++ b/Userland/Utilities/wc.cpp @@ -45,7 +45,7 @@ static void wc_out(Count const& count) outln("{:>14}", count.name); } -static ErrorOr get_count(StringView file_specifier) +static ErrorOr get_count(StringView file_specifier, bool only_bytes) { Count count; @@ -58,9 +58,20 @@ static ErrorOr get_count(StringView file_specifier) } auto file = TRY(Core::InputBufferedFile::create(maybe_file.release_value())); - count.name = file_specifier; + if (only_bytes) { + auto seek_or_error = file->size(); + if (!seek_or_error.is_error()) { + count.bytes = seek_or_error.release_value(); + return count; + } + + // Handle the file as non-seekable if the error indicates it as such. + if (seek_or_error.error().code() != ESPIPE) + return seek_or_error.release_error(); + } + bool start_a_new_word = true; unsigned current_line_length = 0; @@ -118,14 +129,16 @@ ErrorOr serenity_main(Main::Arguments arguments) if (!g_output_line && !g_output_byte && !g_output_word && !g_output_max_line_length) g_output_line = g_output_byte = g_output_word = true; + bool only_bytes = !g_output_line && !g_output_word && !g_output_max_line_length; + Vector counts; for (auto const& file_specifier : file_specifiers) - counts.append(TRY(get_count(file_specifier))); + counts.append(TRY(get_count(file_specifier, only_bytes))); TRY(Core::System::pledge("stdio")); if (file_specifiers.is_empty()) - counts.append(TRY(get_count(""sv))); + counts.append(TRY(get_count(""sv, only_bytes))); else if (file_specifiers.size() > 1) counts.append(get_total_count(counts));