mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 18:57:35 +00:00
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:
parent
9f9dbb325b
commit
5d07c56d0d
1 changed files with 48 additions and 38 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, the SerenityOS developers.
|
* Copyright (c) 2021-2024, the SerenityOS developers.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -12,6 +12,11 @@
|
||||||
#include <LibMain/Main.h>
|
#include <LibMain/Main.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
u32 checksum { 0 };
|
||||||
|
size_t file_size { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
Vector<StringView> paths;
|
Vector<StringView> paths;
|
||||||
|
@ -34,16 +39,49 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
exit(0);
|
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);
|
warnln("{}: Unknown checksum algorithm: {}", arguments.strings[0], algorithm);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paths.is_empty())
|
if (paths.is_empty()) {
|
||||||
paths.append("-"sv);
|
paths.append("-"sv);
|
||||||
|
}
|
||||||
bool fail = false;
|
|
||||||
Array<u8, PAGE_SIZE> buffer;
|
|
||||||
|
|
||||||
for (auto& path : paths) {
|
for (auto& path : paths) {
|
||||||
auto file_or_error = Core::File::open_file_or_standard_stream(path, Core::File::OpenMode::Read);
|
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;
|
fail = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto file = file_or_error.release_value();
|
|
||||||
size_t file_size = 0;
|
|
||||||
|
|
||||||
if (algorithm == "crc32"sv) {
|
auto file = file_or_error.release_value();
|
||||||
Crypto::Checksum::CRC32 crc32;
|
auto data = build_checksum_data_using_file(file.ptr(), path);
|
||||||
while (!file->is_eof()) {
|
|
||||||
auto data_or_error = file->read_some(buffer);
|
outln("{:08x} {} {}", data.checksum, data.file_size, path);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fail;
|
return fail;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue