diff options
author | kleines Filmröllchen <filmroellchen@serenityos.org> | 2023-05-18 15:58:57 +0200 |
---|---|---|
committer | Jelle Raaijmakers <jelle@gmta.nl> | 2023-05-18 22:23:15 +0200 |
commit | 70ab4566f390ba85175147579b7f52cbc4e16b00 (patch) | |
tree | 060d72b15cfe34d38d698dbfadea840011f5eab8 /Userland/Libraries/LibCrypto | |
parent | daf50ed88521dc6e61cd80e57dc00f6a3d3d13bf (diff) | |
download | serenity-70ab4566f390ba85175147579b7f52cbc4e16b00.zip |
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.
Diffstat (limited to 'Userland/Libraries/LibCrypto')
-rw-r--r-- | Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h b/Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h new file mode 100644 index 0000000000..5c71d00d29 --- /dev/null +++ b/Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h @@ -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 {}; +}; + +} |