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 :
23 : namespace chip {
24 : /// @brief Data accessor allowing data to be persisted by PersistentStore to be accessed
25 : struct DataAccessor
26 : {
27 1842 : virtual ~DataAccessor() = default;
28 : virtual CHIP_ERROR UpdateKey(StorageKeyName & key) const = 0;
29 : virtual CHIP_ERROR Serialize(TLV::TLVWriter & writer) const = 0;
30 : virtual CHIP_ERROR Deserialize(TLV::TLVReader & reader) = 0;
31 : virtual void Clear() = 0;
32 : };
33 :
34 : /// @brief Interface to PersistentStorageDelegate allowing storage of data of variable size such as TLV, delegating data access
35 : /// to DataAccessor
36 : /// @tparam kMaxSerializedSize size of the mBuffer necessary to retrieve an entry from the storage. Varies with the type of data
37 : /// stored. Will be allocated on the stack so the implementation needs to be aware of this when choosing this value.
38 : template <size_t kMaxSerializedSize>
39 : struct PersistentStore
40 : {
41 1970 : virtual ~PersistentStore() = default;
42 :
43 569 : CHIP_ERROR Save(const DataAccessor & persistent, PersistentStorageDelegate * storage)
44 : {
45 569 : VerifyOrReturnError(nullptr != storage, CHIP_ERROR_INVALID_ARGUMENT);
46 :
47 569 : StorageKeyName key = StorageKeyName::Uninitialized();
48 569 : ReturnErrorOnFailure(persistent.UpdateKey(key));
49 :
50 : // Serialize the data
51 569 : TLV::TLVWriter writer;
52 569 : writer.Init(mBuffer, sizeof(mBuffer));
53 :
54 569 : ReturnErrorOnFailure(persistent.Serialize(writer));
55 :
56 : // Save serialized data
57 569 : return storage->SyncSetKeyValue(key.KeyName(), mBuffer, static_cast<uint16_t>(writer.GetLengthWritten()));
58 569 : }
59 :
60 2260 : CHIP_ERROR Load(DataAccessor & persistent, PersistentStorageDelegate * storage)
61 : {
62 2260 : VerifyOrReturnError(nullptr != storage, CHIP_ERROR_INVALID_ARGUMENT);
63 :
64 2260 : StorageKeyName key = StorageKeyName::Uninitialized();
65 :
66 : // Update storage key
67 2260 : ReturnErrorOnFailure(persistent.UpdateKey(key));
68 :
69 : // Set data to defaults
70 2258 : persistent.Clear();
71 :
72 : // Load the serialized data
73 2258 : uint16_t size = static_cast<uint16_t>(sizeof(mBuffer));
74 2258 : CHIP_ERROR err = storage->SyncGetKeyValue(key.KeyName(), mBuffer, size);
75 2258 : VerifyOrReturnError(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND != err, CHIP_ERROR_NOT_FOUND);
76 2178 : ReturnErrorOnFailure(err);
77 :
78 : // Decode serialized data
79 2178 : TLV::TLVReader reader;
80 2178 : reader.Init(mBuffer, size);
81 2178 : return persistent.Deserialize(reader);
82 2260 : }
83 :
84 131 : CHIP_ERROR Delete(DataAccessor & persistent, PersistentStorageDelegate * storage)
85 : {
86 131 : VerifyOrReturnError(nullptr != storage, CHIP_ERROR_INVALID_ARGUMENT);
87 :
88 131 : StorageKeyName key = StorageKeyName::Uninitialized();
89 131 : ReturnErrorOnFailure(persistent.UpdateKey(key));
90 :
91 131 : return storage->SyncDeleteKeyValue(key.KeyName());
92 131 : }
93 :
94 : uint8_t mBuffer[kMaxSerializedSize] = { 0 };
95 : };
96 :
97 : /// @brief Combines PersistentStore and DataAccessor
98 : template <size_t kMaxSerializedSize>
99 : struct PersistentData : PersistentStore<kMaxSerializedSize>, DataAccessor
100 : {
101 : using SizedStore = PersistentStore<kMaxSerializedSize>;
102 :
103 1970 : PersistentData(PersistentStorageDelegate * storage = nullptr) : mStorage(storage) {}
104 1970 : virtual ~PersistentData() = default;
105 :
106 0 : virtual CHIP_ERROR Save() { return this->Save(this->mStorage); }
107 :
108 569 : virtual CHIP_ERROR Save(PersistentStorageDelegate * storage) { return SizedStore::Save(*this, storage); }
109 :
110 0 : virtual CHIP_ERROR Load() { return this->Load(this->mStorage); }
111 :
112 2260 : virtual CHIP_ERROR Load(PersistentStorageDelegate * storage) { return SizedStore::Load(*this, storage); }
113 :
114 131 : virtual CHIP_ERROR Delete(PersistentStorageDelegate * storage) { return SizedStore::Delete(*this, storage); }
115 :
116 : PersistentStorageDelegate * mStorage = nullptr;
117 : };
118 :
119 : } // namespace chip
|