ChecksummingStream.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/Concepts.h>
  9. #include <AK/MaybeOwned.h>
  10. #include <AK/Stream.h>
  11. #include <LibCrypto/Checksum/ChecksumFunction.h>
  12. namespace Crypto::Checksum {
  13. // A stream wrapper type which passes all read and written data through a checksum function.
  14. template<typename ChecksumFunctionType, typename ChecksumType = typename ChecksumFunctionType::ChecksumType>
  15. requires(
  16. IsBaseOf<ChecksumFunction<ChecksumType>, ChecksumFunctionType>,
  17. // Require checksum function to be constructible without arguments, since we have no initial data.
  18. requires() {
  19. ChecksumFunctionType {};
  20. })
  21. class ChecksummingStream : public Stream {
  22. public:
  23. virtual ~ChecksummingStream() = default;
  24. ChecksummingStream(MaybeOwned<Stream> stream)
  25. : m_stream(move(stream))
  26. {
  27. }
  28. virtual ErrorOr<Bytes> read_some(Bytes bytes) override
  29. {
  30. auto const written_bytes = TRY(m_stream->read_some(bytes));
  31. update(written_bytes);
  32. return written_bytes;
  33. }
  34. virtual ErrorOr<void> read_until_filled(Bytes bytes) override
  35. {
  36. TRY(m_stream->read_until_filled(bytes));
  37. update(bytes);
  38. return {};
  39. }
  40. virtual ErrorOr<size_t> write_some(ReadonlyBytes bytes) override
  41. {
  42. auto bytes_written = TRY(m_stream->write_some(bytes));
  43. // Only update with the bytes that were actually written
  44. update(bytes.trim(bytes_written));
  45. return bytes_written;
  46. }
  47. virtual ErrorOr<void> write_until_depleted(ReadonlyBytes bytes) override
  48. {
  49. update(bytes);
  50. return m_stream->write_until_depleted(bytes);
  51. }
  52. virtual bool is_eof() const override { return m_stream->is_eof(); }
  53. virtual bool is_open() const override { return m_stream->is_open(); }
  54. virtual void close() override { m_stream->close(); }
  55. ChecksumType digest()
  56. {
  57. return m_checksum.digest();
  58. }
  59. private:
  60. ALWAYS_INLINE void update(ReadonlyBytes bytes)
  61. {
  62. m_checksum.update(bytes);
  63. }
  64. MaybeOwned<Stream> m_stream;
  65. ChecksumFunctionType m_checksum {};
  66. };
  67. }