Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_kvs / public / pw_kvs / checksum.h
1 // Copyright 2020 The Pigweed Authors
2 //
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
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
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
13 // the License.
14 #pragma once
15
16 #include <cstddef>
17 #include <span>
18
19 #include "pw_kvs/alignment.h"
20 #include "pw_status/status.h"
21
22 namespace pw {
23 namespace kvs {
24
25 class ChecksumAlgorithm {
26  public:
27   // Resets the checksum to its initial state.
28   virtual void Reset() = 0;
29
30   // Updates the checksum with the provided data.
31   virtual void Update(std::span<const std::byte> data) = 0;
32
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));
37   }
38
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().
41   //
42   // Finish MUST be called before calling Verify.
43   std::span<const std::byte> Finish() {
44     Finalize();  // Implemented by derived classes, if required.
45     return state();
46   }
47
48   // Returns the size of the checksum state.
49   constexpr size_t size_bytes() const { return state_.size(); }
50
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.
54   //
55   // Finish MUST be called before calling Verify.
56   Status Verify(std::span<const std::byte> checksum) const;
57
58  protected:
59   // A derived class provides a std::span of its state buffer.
60   constexpr ChecksumAlgorithm(std::span<const std::byte> state)
61       : state_(state) {}
62
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;
66
67   // Returns the current checksum state.
68   constexpr std::span<const std::byte> state() const { return state_; }
69
70  private:
71   // Checksums that require finalizing operations may override this method.
72   virtual void Finalize() {}
73
74   std::span<const std::byte> state_;
75 };
76
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 {
80  public:
81   constexpr IgnoreChecksum() : ChecksumAlgorithm({}) {}
82
83   void Reset() override {}
84   void Update(std::span<const std::byte>) override {}
85 };
86
87 // Calculates a checksum in kAlignmentBytes chunks. Checksum classes can inherit
88 // from this and implement UpdateAligned and FinalizeAligned instead of Update
89 // and Finalize.
90 template <size_t kAlignmentBytes, size_t kBufferSize = kAlignmentBytes>
91 class AlignedChecksum : public ChecksumAlgorithm {
92  public:
93   void Update(std::span<const std::byte> data) final { writer_.Write(data); }
94
95  protected:
96   constexpr AlignedChecksum(std::span<const std::byte> state)
97       : ChecksumAlgorithm(state),
98         output_(this),
99         writer_(kAlignmentBytes, output_) {}
100
101   ~AlignedChecksum() = default;
102
103  private:
104   static_assert(kBufferSize >= kAlignmentBytes);
105
106   void Finalize() final {
107     writer_.Flush();
108     FinalizeAligned();
109   }
110
111   virtual void UpdateAligned(std::span<const std::byte> data) = 0;
112
113   virtual void FinalizeAligned() = 0;
114
115   OutputToMethod<void (AlignedChecksum<kAlignmentBytes, kBufferSize>::*)(
116                      std::span<const std::byte>),
117                  &AlignedChecksum::UpdateAligned>
118       output_;
119   AlignedWriterBuffer<kBufferSize> writer_;
120 };
121
122 }  // namespace kvs
123 }  // namespace pw