1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
19 #include "pw_kvs/alignment.h"
20 #include "pw_status/status.h"
25 class ChecksumAlgorithm {
27 // Resets the checksum to its initial state.
28 virtual void Reset() = 0;
30 // Updates the checksum with the provided data.
31 virtual void Update(std::span<const std::byte> data) = 0;
33 // Updates the checksum from a pointer and size.
34 void Update(const void* data, size_t size_bytes) {
35 return Update(std::span<const std::byte>(
36 static_cast<const std::byte*>(data), size_bytes));
39 // Returns the final result of the checksum. Update() can no longer be called
40 // after this. The returned std::span is valid until a call to Reset().
42 // Finish MUST be called before calling Verify.
43 std::span<const std::byte> Finish() {
44 Finalize(); // Implemented by derived classes, if required.
48 // Returns the size of the checksum state.
49 constexpr size_t size_bytes() const { return state_.size(); }
51 // Compares a calculated checksum to this checksum's state. The checksum must
52 // be at least as large as size_bytes(). If it is larger, bytes beyond
53 // size_bytes() are ignored.
55 // Finish MUST be called before calling Verify.
56 Status Verify(std::span<const std::byte> checksum) const;
59 // A derived class provides a std::span of its state buffer.
60 constexpr ChecksumAlgorithm(std::span<const std::byte> state)
63 // Protected destructor prevents deleting ChecksumAlgorithms from the base
64 // class, so that it is safe to have a non-virtual destructor.
65 ~ChecksumAlgorithm() = default;
67 // Returns the current checksum state.
68 constexpr std::span<const std::byte> state() const { return state_; }
71 // Checksums that require finalizing operations may override this method.
72 virtual void Finalize() {}
74 std::span<const std::byte> state_;
77 // A checksum algorithm for which Verify always passes. This can be used to
78 // disable checksum verification for a particular entry format.
79 class IgnoreChecksum final : public ChecksumAlgorithm {
81 constexpr IgnoreChecksum() : ChecksumAlgorithm({}) {}
83 void Reset() override {}
84 void Update(std::span<const std::byte>) override {}
87 // Calculates a checksum in kAlignmentBytes chunks. Checksum classes can inherit
88 // from this and implement UpdateAligned and FinalizeAligned instead of Update
90 template <size_t kAlignmentBytes, size_t kBufferSize = kAlignmentBytes>
91 class AlignedChecksum : public ChecksumAlgorithm {
93 void Update(std::span<const std::byte> data) final { writer_.Write(data); }
96 constexpr AlignedChecksum(std::span<const std::byte> state)
97 : ChecksumAlgorithm(state),
99 writer_(kAlignmentBytes, output_) {}
101 ~AlignedChecksum() = default;
104 static_assert(kBufferSize >= kAlignmentBytes);
106 void Finalize() final {
111 virtual void UpdateAligned(std::span<const std::byte> data) = 0;
113 virtual void FinalizeAligned() = 0;
115 OutputToMethod<void (AlignedChecksum<kAlignmentBytes, kBufferSize>::*)(
116 std::span<const std::byte>),
117 &AlignedChecksum::UpdateAligned>
119 AlignedWriterBuffer<kBufferSize> writer_;