mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:47:45 +00:00
LibCrypto: Add a checksumming stream wrapper
This generic stream wrapper performs checksum calculations on all data passed through it for reading or writing, and is therefore convenient for calculating checksums while performing normal data input/output, as well as computing streaming checksums on non-seekable streams.
This commit is contained in:
parent
daf50ed885
commit
70ab4566f3
1 changed files with 81 additions and 0 deletions
81
Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h
Normal file
81
Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/ByteBuffer.h>
|
||||||
|
#include <AK/Concepts.h>
|
||||||
|
#include <AK/MaybeOwned.h>
|
||||||
|
#include <AK/Stream.h>
|
||||||
|
#include <LibCrypto/Checksum/ChecksumFunction.h>
|
||||||
|
|
||||||
|
namespace Crypto::Checksum {
|
||||||
|
|
||||||
|
// A stream wrapper type which passes all read and written data through a checksum function.
|
||||||
|
template<typename ChecksumFunctionType, typename ChecksumType = typename ChecksumFunctionType::ChecksumType>
|
||||||
|
requires(
|
||||||
|
IsBaseOf<ChecksumFunction<ChecksumType>, ChecksumFunctionType>,
|
||||||
|
// Require checksum function to be constructible without arguments, since we have no initial data.
|
||||||
|
requires() {
|
||||||
|
ChecksumFunctionType {};
|
||||||
|
})
|
||||||
|
class ChecksummingStream : public Stream {
|
||||||
|
public:
|
||||||
|
virtual ~ChecksummingStream() = default;
|
||||||
|
|
||||||
|
ChecksummingStream(MaybeOwned<Stream> stream)
|
||||||
|
: m_stream(move(stream))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ErrorOr<Bytes> read_some(Bytes bytes) override
|
||||||
|
{
|
||||||
|
auto const written_bytes = TRY(m_stream->read_some(bytes));
|
||||||
|
update(written_bytes);
|
||||||
|
return written_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ErrorOr<void> read_until_filled(Bytes bytes) override
|
||||||
|
{
|
||||||
|
TRY(m_stream->read_until_filled(bytes));
|
||||||
|
update(bytes);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ErrorOr<size_t> write_some(ReadonlyBytes bytes) override
|
||||||
|
{
|
||||||
|
auto bytes_written = TRY(m_stream->write_some(bytes));
|
||||||
|
// Only update with the bytes that were actually written
|
||||||
|
update(bytes.trim(bytes_written));
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ErrorOr<void> write_until_depleted(ReadonlyBytes bytes) override
|
||||||
|
{
|
||||||
|
update(bytes);
|
||||||
|
return m_stream->write_until_depleted(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool is_eof() const override { return m_stream->is_eof(); }
|
||||||
|
virtual bool is_open() const override { return m_stream->is_open(); }
|
||||||
|
virtual void close() override { m_stream->close(); }
|
||||||
|
|
||||||
|
ChecksumType digest()
|
||||||
|
{
|
||||||
|
return m_checksum.digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ALWAYS_INLINE void update(ReadonlyBytes bytes)
|
||||||
|
{
|
||||||
|
m_checksum.update(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeOwned<Stream> m_stream;
|
||||||
|
ChecksumFunctionType m_checksum {};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue