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