3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2016-2017 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * Implementation of a simple std::map based persisted store.
26 #ifndef __STDC_FORMAT_MACROS
27 #define __STDC_FORMAT_MACROS
30 #ifndef __STDC_LIMIT_MACROS
31 #define __STDC_LIMIT_MACROS
38 #include <platform/PersistedStorage.h>
39 #include <support/Base64.h>
40 #include <support/CHIPArgParser.hpp>
41 #include <support/CodeUtils.h>
43 #include "TestPersistedStorageImplementation.h"
45 using namespace chip::ArgParser;
47 std::map<std::string, std::string> sPersistentStore;
49 FILE * sPersistentStoreFile = nullptr;
53 namespace PersistedStorage {
55 static void RemoveEndOfLineSymbol(char * str)
57 size_t len = strlen(str) - 1;
62 static CHIP_ERROR GetCounterValueFromFile(const char * aKey, uint32_t & aValue)
64 CHIP_ERROR err = CHIP_NO_ERROR;
65 char key[CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH];
66 char value[CHIP_CONFIG_PERSISTED_STORAGE_MAX_VALUE_LENGTH];
68 rewind(sPersistentStoreFile);
70 while (fgets(key, sizeof(key), sPersistentStoreFile) != nullptr)
72 RemoveEndOfLineSymbol(key);
74 if (strcmp(key, aKey) == 0)
76 if (fgets(value, sizeof(value), sPersistentStoreFile) == nullptr)
78 err = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
82 RemoveEndOfLineSymbol(value);
84 if (!ParseInt(value, aValue, 0))
85 err = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
92 err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
98 static CHIP_ERROR SaveCounterValueToFile(const char * aKey, uint32_t aValue)
100 CHIP_ERROR err = CHIP_NO_ERROR;
102 char key[CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH];
103 char value[CHIP_CONFIG_PERSISTED_STORAGE_MAX_VALUE_LENGTH];
105 snprintf(value, sizeof(value), "0x%08X\n", aValue);
107 rewind(sPersistentStoreFile);
109 // Find the stored counter value location in the file.
110 while (fgets(key, sizeof(key), sPersistentStoreFile) != nullptr)
112 RemoveEndOfLineSymbol(key);
114 // If value is found in the file then override it.
115 if (strcmp(key, aKey) == 0)
117 res = fputs(value, sPersistentStoreFile);
118 VerifyOrExit(res != EOF, err = CHIP_ERROR_PERSISTED_STORAGE_FAILED);
124 // If value not found in the file then write the counter key and
125 // the counter value to the end of the file.
126 res = fputs(aKey, sPersistentStoreFile);
127 VerifyOrExit(res != EOF, err = CHIP_ERROR_PERSISTED_STORAGE_FAILED);
129 res = fputs("\n", sPersistentStoreFile);
130 VerifyOrExit(res != EOF, err = CHIP_ERROR_PERSISTED_STORAGE_FAILED);
132 res = fputs(value, sPersistentStoreFile);
133 VerifyOrExit(res != EOF, err = CHIP_ERROR_PERSISTED_STORAGE_FAILED);
136 fflush(sPersistentStoreFile);
140 CHIP_ERROR Read(const char * aKey, uint32_t & aValue)
142 CHIP_ERROR err = CHIP_NO_ERROR;
143 std::map<std::string, std::string>::iterator it;
145 VerifyOrExit(aKey != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
146 VerifyOrExit(strlen(aKey) <= CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH, err = CHIP_ERROR_INVALID_STRING_LENGTH);
148 if (sPersistentStoreFile)
150 err = GetCounterValueFromFile(aKey, aValue);
154 it = sPersistentStore.find(aKey);
155 VerifyOrExit(it != sPersistentStore.end(), err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
157 size_t aValueLength =
158 Base64Decode(it->second.c_str(), static_cast<uint16_t>(it->second.length()), reinterpret_cast<uint8_t *>(&aValue));
159 VerifyOrExit(aValueLength == sizeof(uint32_t), err = CHIP_ERROR_PERSISTED_STORAGE_FAILED);
166 CHIP_ERROR Write(const char * aKey, uint32_t aValue)
168 CHIP_ERROR err = CHIP_NO_ERROR;
170 VerifyOrExit(aKey != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
171 VerifyOrExit(strlen(aKey) <= CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH, err = CHIP_ERROR_INVALID_STRING_LENGTH);
173 if (sPersistentStoreFile)
175 err = SaveCounterValueToFile(aKey, aValue);
179 char encodedValue[BASE64_ENCODED_LEN(sizeof(uint32_t)) + 1];
181 memset(encodedValue, 0, sizeof(encodedValue));
182 Base64Encode(reinterpret_cast<uint8_t *>(&aValue), sizeof(aValue), encodedValue);
184 sPersistentStore[aKey] = encodedValue;
191 } // namespace PersistedStorage
192 } // namespace Platform