From d72158045c69fc72f57d18cf48fde896a52f139d Mon Sep 17 00:00:00 2001 From: Pankaj Raghav Date: Fri, 19 Nov 2021 11:17:40 +0530 Subject: [PATCH] Hexdump: Allow identical lines to coalesce Coalesce feature is enabled by default when using the program. Any number of lines identical to the preceding line will be replaced by a single asterik. --- Userland/Utilities/hexdump.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Userland/Utilities/hexdump.cpp b/Userland/Utilities/hexdump.cpp index 2a8c08aff3..be9d5e73df 100644 --- a/Userland/Utilities/hexdump.cpp +++ b/Userland/Utilities/hexdump.cpp @@ -12,6 +12,12 @@ static constexpr size_t LINE_LENGTH_BYTES = 16; +enum class State { + Print, + PrintFiller, + SkipPrint +}; + int main(int argc, char** argv) { Core::ArgsParser args_parser; @@ -59,20 +65,42 @@ int main(int argc, char** argv) }; Array contents; + Span previous_line; static_assert(LINE_LENGTH_BYTES * 2 <= contents.size(), "Buffer is too small?!"); size_t contents_size = 0; int nread; + auto state = State::Print; while (true) { nread = file->read(&contents[contents_size], BUFSIZ - contents_size); if (nread <= 0) break; contents_size += nread; - // Print as many complete lines as we can (possibly none). + size_t offset; for (offset = 0; offset + LINE_LENGTH_BYTES - 1 < contents_size; offset += LINE_LENGTH_BYTES) { - print_line(&contents[offset], LINE_LENGTH_BYTES); + auto current_line = contents.span().slice(offset, LINE_LENGTH_BYTES); + bool is_same_contents = (current_line == previous_line); + if (!is_same_contents) + state = State::Print; + else if (is_same_contents && (state != State::SkipPrint)) + state = State::PrintFiller; + + // Coalesce repeating lines + switch (state) { + case State::Print: + print_line(&contents[offset], LINE_LENGTH_BYTES); + break; + case State::PrintFiller: + outln("*"); + state = State::SkipPrint; + break; + case State::SkipPrint: + break; + } + previous_line = current_line; } + contents_size -= offset; VERIFY(contents_size < LINE_LENGTH_BYTES); // If we managed to make the buffer exactly full, &contents[BUFSIZ] would blow up.