Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2022 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 : #pragma once
18 :
19 : #include <lib/core/CHIPPersistentStorageDelegate.h>
20 : #include <lib/core/TLV.h>
21 : #include <lib/support/DefaultStorageKeyAllocator.h>
22 : #include <lib/support/Span.h>
23 :
24 : namespace chip {
25 :
26 : /// @brief Data that can be persisted via PersistentStorageDelegate in TLV format.
27 : struct DataAccessor
28 : {
29 7866 : virtual ~DataAccessor() = default;
30 : virtual CHIP_ERROR UpdateKey(StorageKeyName & key) const = 0;
31 : virtual CHIP_ERROR Serialize(TLV::TLVWriter & writer) const = 0;
32 : virtual CHIP_ERROR Deserialize(TLV::TLVReader & reader) = 0;
33 : virtual void Clear() = 0;
34 :
35 : /// Non-virtual helper methods ///
36 :
37 3121 : CHIP_ERROR Save(PersistentStorageDelegate * storage, const MutableByteSpan & buffer) const
38 : {
39 3121 : VerifyOrReturnError(nullptr != storage, CHIP_ERROR_INVALID_ARGUMENT);
40 :
41 3121 : StorageKeyName key = StorageKeyName::Uninitialized();
42 3121 : ReturnErrorOnFailure(this->UpdateKey(key));
43 :
44 : // Serialize the data
45 3121 : TLV::TLVWriter writer;
46 3121 : writer.Init(buffer);
47 3121 : ReturnErrorOnFailure(this->Serialize(writer));
48 :
49 : // Save serialized data
50 3121 : return storage->SyncSetKeyValue(key.KeyName(), buffer.data(), static_cast<uint16_t>(writer.GetLengthWritten()));
51 3121 : }
52 :
53 6423 : CHIP_ERROR Load(PersistentStorageDelegate * storage, const MutableByteSpan & buffer)
54 : {
55 6423 : VerifyOrReturnError(nullptr != storage, CHIP_ERROR_INVALID_ARGUMENT);
56 :
57 6423 : StorageKeyName key = StorageKeyName::Uninitialized();
58 6423 : ReturnErrorOnFailure(this->UpdateKey(key));
59 :
60 : // Set data to defaults
61 6421 : this->Clear();
62 :
63 : // Load the serialized data
64 6421 : uint16_t size = (buffer.size() > UINT16_MAX) ? UINT16_MAX : static_cast<uint16_t>(buffer.size());
65 6421 : CHIP_ERROR err = storage->SyncGetKeyValue(key.KeyName(), buffer.data(), size);
66 12842 : VerifyOrReturnError(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND != err, CHIP_ERROR_NOT_FOUND);
67 6089 : ReturnErrorOnFailure(err);
68 :
69 : // Decode serialized data
70 6089 : TLV::TLVReader reader;
71 6089 : reader.Init(buffer.data(), size);
72 6089 : return this->Deserialize(reader);
73 6423 : }
74 :
75 150 : CHIP_ERROR Delete(PersistentStorageDelegate * storage) const
76 : {
77 150 : VerifyOrReturnError(nullptr != storage, CHIP_ERROR_INVALID_ARGUMENT);
78 :
79 150 : StorageKeyName key = StorageKeyName::Uninitialized();
80 150 : ReturnErrorOnFailure(this->UpdateKey(key));
81 :
82 150 : return storage->SyncDeleteKeyValue(key.KeyName());
83 150 : }
84 : };
85 :
86 : /// @brief A buffer to be used when loading or serializing persistent data
87 : /// @tparam kMaxSerializedSize size of the buffer necessary to retrieve an entry from the storage.
88 : ///
89 : /// Note: Generic APIs that utilize a persistence buffer should prefer taking
90 : /// a MutableByteSpan, to avoid unnecessarily templating on the buffer size.
91 : template <size_t kMaxSerializedSize>
92 : struct PersistenceBuffer
93 : {
94 : uint8_t mBuffer[kMaxSerializedSize];
95 :
96 : // Returns a MutableByteSpan representing this buffer.
97 9544 : MutableByteSpan BufferSpan() { return MutableByteSpan(mBuffer); }
98 : };
99 :
100 : /// @brief A DataAccessor with a built-in buffer.
101 : /// @tparam kMaxSerializedSize inherited from PersistenceBuffer
102 : ///
103 : /// Note: Unlike `PersistentData` (deprecated), this class does not make the Load/Save/Delete
104 : /// methods virtual. PersistableData objects are not intended to be used polymorphically.
105 : /// It also does not store a PersistentStorageDelegate pointer internally.
106 : template <size_t kMaxSerializedSize>
107 : class PersistableData : public DataAccessor, protected PersistenceBuffer<kMaxSerializedSize>
108 : {
109 : public:
110 2916 : CHIP_ERROR Save(PersistentStorageDelegate * storage) { return DataAccessor::Save(storage, this->BufferSpan()); }
111 6309 : CHIP_ERROR Load(PersistentStorageDelegate * storage) { return DataAccessor::Load(storage, this->BufferSpan()); }
112 : };
113 :
114 : ///// Deprecated types retained for backward compatibility ////////////////////
115 :
116 : // Deprecated: use PersistenceBuffer and DataAccessor separately
117 : template <size_t kMaxSerializedSize>
118 : struct PersistentStore : public PersistenceBuffer<kMaxSerializedSize>
119 : {
120 : virtual ~PersistentStore() = default;
121 :
122 : CHIP_ERROR Save(const DataAccessor & persistent, PersistentStorageDelegate * storage)
123 : {
124 : return persistent.Save(storage, this->BufferSpan());
125 : }
126 :
127 : CHIP_ERROR Load(DataAccessor & persistent, PersistentStorageDelegate * storage)
128 : {
129 : return persistent.Load(storage, this->BufferSpan());
130 : }
131 :
132 : CHIP_ERROR Delete(DataAccessor & persistent, PersistentStorageDelegate * storage) { return persistent.Delete(storage); }
133 : };
134 :
135 : // Deprecated: use PersistableData instead
136 : template <size_t kMaxSerializedSize>
137 : struct PersistentData : PersistentStore<kMaxSerializedSize>, DataAccessor
138 : {
139 : using SizedStore = PersistentStore<kMaxSerializedSize>;
140 :
141 : PersistentData(PersistentStorageDelegate * storage = nullptr) : mStorage(storage) {}
142 : virtual ~PersistentData() = default;
143 :
144 : virtual CHIP_ERROR Save() { return this->Save(this->mStorage); }
145 :
146 : virtual CHIP_ERROR Save(PersistentStorageDelegate * storage) { return SizedStore::Save(*this, storage); }
147 :
148 : virtual CHIP_ERROR Load() { return this->Load(this->mStorage); }
149 :
150 : virtual CHIP_ERROR Load(PersistentStorageDelegate * storage) { return SizedStore::Load(*this, storage); }
151 :
152 : virtual CHIP_ERROR Delete(PersistentStorageDelegate * storage) { return SizedStore::Delete(*this, storage); }
153 :
154 : PersistentStorageDelegate * mStorage = nullptr;
155 : };
156 :
157 : } // namespace chip
|