cksum: Decouple printing logic from checksum construction

This is to avoid duplicating the printing logic and so that we can
have an alternative way of printing the result (i.e. for the next
commit that will print without a pathname if no file operands were
provided). This also has us avoid the algorithm checks in the for
loop.
This commit is contained in:
Kemal Zebari 2024-01-15 19:30:28 -08:00 committed by Andrew Kaster
parent 9f9dbb325b
commit 5d07c56d0d
Notes: sideshowbarker 2024-07-16 19:42:24 +09:00

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2021-2024, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -12,6 +12,11 @@
#include <LibMain/Main.h>
#include <string.h>
struct Data {
u32 checksum { 0 };
size_t file_size { 0 };
};
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
Vector<StringView> paths;
@ -34,16 +39,49 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
exit(0);
}
if (!available_algorithms.contains_slow(algorithm)) {
Array<u8, PAGE_SIZE> buffer;
bool fail = false;
Function<Data(Core::File*, StringView path)> build_checksum_data_using_file;
if (algorithm == "crc32") {
build_checksum_data_using_file = [&buffer, &arguments, &fail](Core::File* file, StringView path) {
Crypto::Checksum::CRC32 crc32;
size_t file_size = 0;
while (!file->is_eof()) {
auto data_or_error = file->read_some(buffer);
if (data_or_error.is_error()) {
warnln("{}: Failed to read {}: {}", arguments.strings[0], path, data_or_error.error());
fail = true;
continue;
}
file_size += data_or_error.value().size();
crc32.update(data_or_error.value());
}
return Data { .checksum = crc32.digest(), .file_size = file_size };
};
} else if (algorithm == "adler32") {
build_checksum_data_using_file = [&buffer, &arguments, &fail](Core::File* file, StringView path) {
Crypto::Checksum::Adler32 adler32;
size_t file_size = 0;
while (!file->is_eof()) {
auto data_or_error = file->read_some(buffer);
if (data_or_error.is_error()) {
warnln("{}: Failed to read {}: {}", arguments.strings[0], path, data_or_error.error());
fail = true;
continue;
}
file_size += data_or_error.value().size();
adler32.update(data_or_error.value());
}
return Data { .checksum = adler32.digest(), .file_size = file_size };
};
} else {
warnln("{}: Unknown checksum algorithm: {}", arguments.strings[0], algorithm);
exit(1);
}
if (paths.is_empty())
if (paths.is_empty()) {
paths.append("-"sv);
bool fail = false;
Array<u8, PAGE_SIZE> buffer;
}
for (auto& path : paths) {
auto file_or_error = Core::File::open_file_or_standard_stream(path, Core::File::OpenMode::Read);
@ -53,39 +91,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
fail = true;
continue;
}
auto file = file_or_error.release_value();
size_t file_size = 0;
if (algorithm == "crc32"sv) {
Crypto::Checksum::CRC32 crc32;
while (!file->is_eof()) {
auto data_or_error = file->read_some(buffer);
if (data_or_error.is_error()) {
warnln("{}: Failed to read {}: {}", arguments.strings[0], filepath, data_or_error.error());
fail = true;
continue;
}
file_size += data_or_error.value().size();
crc32.update(data_or_error.value());
}
outln("{:08x} {} {}", crc32.digest(), file_size, path);
} else if (algorithm == "adler32"sv) {
Crypto::Checksum::Adler32 adler32;
while (!file->is_eof()) {
auto data_or_error = file->read_some(buffer);
if (data_or_error.is_error()) {
warnln("{}: Failed to read {}: {}", arguments.strings[0], filepath, data_or_error.error());
fail = true;
continue;
}
file_size += data_or_error.value().size();
adler32.update(data_or_error.value());
}
outln("{:08x} {} {}", adler32.digest(), file_size, path);
} else {
warnln("{}: Unknown checksum algorithm: {}", arguments.strings[0], algorithm);
exit(1);
}
auto file = file_or_error.release_value();
auto data = build_checksum_data_using_file(file.ptr(), path);
outln("{:08x} {} {}", data.checksum, data.file_size, path);
}
return fail;