C/C++ API Reference
Loading...
Searching...
No Matches
persistent_buffer.h
1// Copyright 2021 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 <cstdint>
17#include <cstring>
18#include <type_traits>
19#include <utility>
20
21#include "pw_bytes/span.h"
22#include "pw_checksum/crc16_ccitt.h"
23#include "pw_preprocessor/compiler.h"
24#include "pw_span/span.h"
25#include "pw_status/status.h"
26#include "pw_stream/stream.h"
27
28namespace pw::persistent_ram {
29
31
38 public:
39 PersistentBufferWriter() = delete;
40
41 private:
42 template <size_t>
43 friend class PersistentBuffer;
44
46 volatile size_t& size,
47 volatile uint16_t& checksum)
48 : buffer_(buffer), size_(size), checksum_(checksum) {}
49
50 // Implementation for writing data to this stream.
52
53 size_t ConservativeLimit(LimitType limit) const override {
54 if (limit == LimitType::kWrite) {
55 return buffer_.size_bytes() - size_;
56 }
57 return 0;
58 }
59
60 ByteSpan buffer_;
61 volatile size_t& size_;
62 volatile uint16_t& checksum_;
63};
64
65// The PersistentBuffer class intentionally uses uninitialized memory, which
66// triggers compiler warnings. Disable those warnings for this file.
68PW_MODIFY_DIAGNOSTIC(ignored, "-Wuninitialized");
69PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wmaybe-uninitialized");
70
92template <size_t kMaxSizeBytes>
94 public:
95 // The default constructor intentionally does not initialize anything. This
96 // allows a persistent buffer statically allocated in persistent RAM to be
97 // highly available.
98 //
99 // Explicitly declaring an empty constructor rather than using the default
100 // constructor prevents the object from being zero-initialized when the object
101 // is value initialized. If this was left as a default constructor,
102 // PersistentBuffer objects declared as value-initialized would be
103 // zero-initialized.
104 //
105 // // Value initialization:
106 // PersistentBuffer<256> persistent_buffer();
107 //
108 // // Default initialization:
109 // PersistentBuffer<256> persistent_buffer;
111 // Disable copy and move constructors.
112 PersistentBuffer(const PersistentBuffer&) = delete;
114 // Explicit no-op destructor.
116
117 PersistentBufferWriter GetWriter() {
118 if (!has_value()) {
119 clear();
120 }
122 ByteSpan(const_cast<std::byte*>(buffer_), kMaxSizeBytes),
123 size_,
124 checksum_);
125 }
126
127 size_t size() const {
128 if (has_value()) {
129 return size_;
130 }
131 return 0;
132 }
133
134 const std::byte* data() const { return const_cast<std::byte*>(buffer_); }
135
136 void clear() {
137 size_ = 0;
138 checksum_ = checksum::Crc16Ccitt::kInitialValue;
139 }
140
141 bool has_value() const {
142 if (size_ > kMaxSizeBytes || size_ == 0) {
143 return false;
144 }
145
146 // Check checksum. This is more costly.
147 return checksum_ == checksum::Crc16Ccitt::Calculate(ConstByteSpan(
148 const_cast<std::byte*>(buffer_), size_));
149 }
150
151 private:
152 // None of these members are initialized by the constructor by design.
153 volatile uint16_t checksum_;
154 volatile size_t size_;
155 volatile std::byte buffer_[kMaxSizeBytes];
156};
157
159
160} // namespace pw::persistent_ram
Definition: status.h:109
Definition: persistent_buffer.h:93
Definition: persistent_buffer.h:37
Definition: stream.h:504
size_t ConservativeLimit(LimitType limit) const override
Definition: persistent_buffer.h:53
Status DoWrite(ConstByteSpan data) override
Virtual Write() function implemented by derived classes.
#define PW_MODIFY_DIAGNOSTICS_POP()
Definition: compiler.h:194
#define PW_MODIFY_DIAGNOSTIC(kind, option)
Definition: compiler.h:203
#define PW_MODIFY_DIAGNOSTIC_GCC(kind, option)
Definition: compiler.h:211
#define PW_MODIFY_DIAGNOSTICS_PUSH()
Definition: compiler.h:189
Persistent RAM utilities and containers.
Definition: persistent.h:28