Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 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 :
18 : /**
19 : * @file
20 : *
21 : * @brief
22 : * API function declarations for using persistent key value storage.
23 : */
24 :
25 : #pragma once
26 :
27 : #include <climits>
28 : #include <cstddef>
29 : #include <cstdint>
30 : #include <type_traits>
31 :
32 : #include <lib/core/CHIPError.h>
33 : #include <platform/CHIPDeviceConfig.h>
34 :
35 : namespace chip {
36 : namespace DeviceLayer {
37 : namespace PersistedStorage {
38 : class KeyValueStoreManagerImpl;
39 :
40 : class KeyValueStoreManager
41 : {
42 : public:
43 : /**
44 : * @brief
45 : * Reads the value of an entry in the KVS. The value is read into the
46 : * provided buffer and the number of bytes read is returned. If desired,
47 : * the read can be started at an offset.
48 : *
49 : * If the output buffer is too small for the value, Get returns
50 : * CHIP_ERROR_BUFFER_TOO_SMALL with the number of bytes read returned in
51 : * read_bytes_size, which should be the buffer_size.
52 : *
53 : * The remainder of the value can be read by calling get with an offset.
54 : *
55 : * @param[in] key The name of the key to get, this is a
56 : * null-terminated string.
57 : * @param[in,out] buffer A buffer to read the value into.
58 : * @param[in] buffer_size The size of the buffer in bytes.
59 : * @param[in] read_bytes_size The number of bytes which were
60 : * copied into the buffer. Optionally can
61 : * provide nullptr if not needed.
62 : * @param[in] offset_bytes The offset byte index to start the read.
63 : *
64 : * @return CHIP_NO_ERROR the entry was successfully read
65 : * CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND the key is not
66 : * present in the KVS
67 : * CHIP_ERROR_INTEGRITY_CHECK_FAILED found the entry, but the data
68 : * was corrupted
69 : * CHIP_ERROR_BUFFER_TOO_SMALL the buffer could not fit the entire
70 : * value, but as many bytes as possible
71 : * were written to it
72 : * CHIP_ERROR_UNINITIALIZED the KVS is not initialized
73 : * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long or value is
74 : * too large
75 : */
76 : CHIP_ERROR Get(const char * key, void * buffer, size_t buffer_size, size_t * read_bytes_size = nullptr,
77 : size_t offset_bytes = 0);
78 :
79 : /**
80 : * @brief
81 : * This overload of Get accepts a pointer to a trivially copyable object.
82 : * The size of the object is inferred from the type.
83 : *
84 : * @param[in] key The name of the key in to get, this is a
85 : * null-terminated string.
86 : * @param[in,out] value Pointer to a trivially copyable object.
87 : *
88 : * @return CHIP_NO_ERROR the entry was successfully read
89 : * CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND the key is not
90 : * present in the KVS
91 : * CHIP_ERROR_INTEGRITY_CHECK_FAILED found the entry, but the data
92 : * was corrupted
93 : * CHIP_ERROR_BUFFER_TOO_SMALL the buffer could not fit the entire
94 : * value, but as many bytes as possible
95 : * were written to it
96 : * CHIP_ERROR_UNINITIALIZED the KVS is not initialized
97 : * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long or value is
98 : * too large
99 : */
100 : template <typename T>
101 : CHIP_ERROR Get(const char * key, T * value)
102 : {
103 : static_assert(std::is_trivially_copyable<T>(), "KVS values must copyable");
104 : static_assert(!std::is_pointer<T>(), "KVS values cannot be pointers");
105 : static_assert(CHAR_BIT == 8, "Current implementation assumes 8 bit.");
106 : return Get(key, value, sizeof(T));
107 : }
108 :
109 : /**
110 : * @brief
111 : * Adds a key-value entry to the KVS. If the key was already present, its
112 : * value is overwritten.
113 : *
114 : * @param[in] key The name of the key to update, this is a
115 : * null-terminated string.
116 : * @param[in] value Pointer to the data.
117 : * @param[in] value_size Size of the data.
118 : *
119 : * @return CHIP_NO_ERROR the entry was successfully added or updated
120 : * CHIP_ERROR_INTEGRITY_CHECK_FAILED checksum validation failed after
121 : * writing the data
122 : * CHIP_ERROR_PERSISTED_STORAGE_FAILED failed to write the value.
123 : * CHIP_ERROR_UNINITIALIZED the KVS is not initialized
124 : * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long or value is
125 : * too large
126 : */
127 : CHIP_ERROR Put(const char * key, const void * value, size_t value_size);
128 :
129 : /**
130 : * @brief
131 : * This overload of Put accepts a reference to a trivially copyable object.
132 : * The size of the object is inferred from the type.
133 : *
134 : * @param[in] key The name of the key to update, this is a
135 : * null-terminated string.
136 : * @param[in] value Reference of a trivially copyable object.
137 : *
138 : * @return CHIP_NO_ERROR the entry was successfully added or updated
139 : * CHIP_ERROR_INTEGRITY_CHECK_FAILED checksum validation failed after
140 : * writing the data
141 : * CHIP_ERROR_PERSISTED_STORAGE_FAILED failed to write the value.
142 : * CHIP_ERROR_UNINITIALIZED the KVS is not initialized
143 : * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long or value is
144 : * too large
145 : */
146 : template <typename T>
147 : CHIP_ERROR Put(const char * key, const T & value)
148 : {
149 : static_assert(std::is_trivially_copyable<T>(), "KVS values must copyable");
150 : static_assert(!std::is_pointer<T>(), "KVS values cannot be pointers");
151 : static_assert(CHAR_BIT == 8, "Current implementation assumes 8 bit.");
152 : return Put(key, &value, sizeof(T));
153 : }
154 :
155 : /**
156 : * @brief
157 : * Removes a key-value entry from the KVS.
158 : *
159 : * @param[in] key The name of the key to delete, this is a
160 : * null-terminated string.
161 : *
162 : * @return CHIP_NO_ERROR the entry was successfully deleted.
163 : * CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND the key is not
164 : * present in the KVS
165 : * CHIP_ERROR_INTEGRITY_CHECK_FAILED checksum validation failed after
166 : * erasing data
167 : * CHIP_ERROR_PERSISTED_STORAGE_FAILED failed to erase the value.
168 : * CHIP_ERROR_UNINITIALIZED the KVS is not initialized
169 : * CHIP_ERROR_INVALID_ARGUMENT key is empty or too long
170 : */
171 : CHIP_ERROR Delete(const char * key);
172 :
173 : private:
174 : using ImplClass = ::chip::DeviceLayer::PersistedStorage::KeyValueStoreManagerImpl;
175 :
176 : protected:
177 : // Construction/destruction limited to subclasses.
178 : KeyValueStoreManager() = default;
179 : ~KeyValueStoreManager() = default;
180 :
181 : // No copy, move or assignment.
182 : KeyValueStoreManager(const KeyValueStoreManager &) = delete;
183 : KeyValueStoreManager(const KeyValueStoreManager &&) = delete;
184 : KeyValueStoreManager & operator=(const KeyValueStoreManager &) = delete;
185 : };
186 :
187 : /**
188 : * Returns a reference to the public interface of the KeyValueStoreManager singleton object.
189 : *
190 : * chip application should use this to access features of the KeyValueStoreManager object
191 : * that are common to all platforms.
192 : */
193 : extern KeyValueStoreManager & KeyValueStoreMgr();
194 :
195 : /**
196 : * Returns the platform-specific implementation of the KeyValueStoreManager singleton object.
197 : *
198 : * chip applications can use this to gain access to features of the KeyValueStoreManager
199 : * that are specific to the selected platform.
200 : */
201 : extern KeyValueStoreManagerImpl & KeyValueStoreMgrImpl();
202 :
203 : } // namespace PersistedStorage
204 : } // namespace DeviceLayer
205 : } // namespace chip
206 :
207 : /* Include a header file containing the implementation of the KeyValueStoreManager
208 : * object for the selected platform.
209 : */
210 : #ifdef EXTERNAL_KEYVALUESTOREMANAGERIMPL_HEADER
211 : #include EXTERNAL_KEYVALUESTOREMANAGERIMPL_HEADER
212 : #elif defined(CHIP_DEVICE_LAYER_TARGET)
213 : #define KEYVALUESTOREMANAGERIMPL_HEADER <platform/CHIP_DEVICE_LAYER_TARGET/KeyValueStoreManagerImpl.h>
214 : #include KEYVALUESTOREMANAGERIMPL_HEADER
215 : #endif // defined(CHIP_DEVICE_LAYER_TARGET)
216 :
217 : namespace chip {
218 : namespace DeviceLayer {
219 : namespace PersistedStorage {
220 5 : inline CHIP_ERROR KeyValueStoreManager::Put(const char * key, const void * value, size_t value_size)
221 : {
222 5 : return static_cast<ImplClass *>(this)->_Put(key, value, value_size);
223 : }
224 :
225 55 : inline CHIP_ERROR KeyValueStoreManager::Get(const char * key, void * buffer, size_t buffer_size, size_t * read_bytes_size,
226 : size_t offset_bytes)
227 : {
228 55 : return static_cast<ImplClass *>(this)->_Get(key, buffer, buffer_size, read_bytes_size, offset_bytes);
229 : }
230 :
231 0 : inline CHIP_ERROR KeyValueStoreManager::Delete(const char * key)
232 : {
233 0 : return static_cast<ImplClass *>(this)->_Delete(key);
234 : }
235 :
236 : } // namespace PersistedStorage
237 : } // namespace DeviceLayer
238 : } // namespace chip
|