1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 08:14:58 +00:00

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.
This commit is contained in:
Pankaj Raghav 2021-11-19 11:17:40 +05:30 committed by Ali Mohammad Pur
parent e08d213830
commit d72158045c

View file

@ -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<u8, BUFSIZ> contents;
Span<u8> 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.