Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
keystore.hpp
Go to the documentation of this file.
1
5#ifndef MODES_HARDWARD_KEYSTORE_HPP
6#define MODES_HARDWARD_KEYSTORE_HPP
7
10
13
14#include <cstring>
15#include <array>
16
19
33static constexpr uint32_t storeUid = utils::hash("StoreRev:v01");
34
36static constexpr uint32_t map32to31hash(uint32_t a)
37{
38 uint32_t lsb = a & 0b1; // mix the lost LSB info into the 13th bit
39 uint32_t val = (a ^ storeUid ^ (lsb << 14));
40 return val >> 1;
41}
42
44template<int16_t N> static constexpr uint32_t LMBD_INLINE hash(const char (&s)[N])
45{
46 static_assert(N - 1 <= 14, "Please use keys shorter than 14 bytes!");
47 return map32to31hash(utils::hash(s, N));
48}
49
55template<int16_t N> static inline void LMBD_INLINE setValue(const char (&key)[N], uint32_t value)
56{
57 static_assert(N - 1 <= 14, "Please use keys shorter than 14 bytes!");
59}
60
67template<int16_t N> static inline bool LMBD_INLINE getValue(const char (&key)[N], uint32_t& out)
68{
69 static_assert(N - 1 <= 14, "Please use keys shorter than 14 bytes!");
70 return physical::fileSystem::user::get_value(hash(key), out);
71}
72
74static inline void clear_stored() { physical::fileSystem::clear(); }
75
81static inline void LMBD_INLINE migrateIfNeeded()
82{
84 {
85 physical::fileSystem::user::set_value(storeUid, storeUid);
86 }
87
88 uint32_t out = storeUid ^ 0xff;
89 if (not physical::fileSystem::user::get_value(storeUid, out))
90 {
91 physical::fileSystem::user::set_value(storeUid, storeUid);
93 }
94
95 if (out != storeUid)
96 {
99 physical::fileSystem::user::set_value(storeUid, storeUid);
102
105 }
106}
107
116static constexpr uint32_t indexKeyFlag = (1 << 31);
117
134enum class PrefixValues : uint32_t
135{
136 generalKeys = indexKeyFlag | (0x0 << 29),
137 managerKeys = indexKeyFlag | (0x1 << 29),
138 privateKeys = indexKeyFlag | (0x2 << 29),
139 invalidKeys = indexKeyFlag | (0x3 << 29),
140};
141
143static constexpr uint32_t noGroupIndex = 15;
144
146static constexpr uint32_t noModeIndex = 31;
147
149static constexpr uint32_t LMBD_INLINE
150indexKeyFor(PrefixValues prefix, uint32_t groupId, uint32_t modeId, uint32_t offset, uint32_t index)
151{
152 uint32_t rawPrefix = (uint32_t)prefix;
153
154 assert((rawPrefix >> 31) == 0b1); // prefix on 2 of the MSBs +indexKeyFlag
155 assert((groupId >> 4) == 0); // groupId on 4 bits (0-14)
156 assert((modeId >> 5) == 0); // modeId on 5 bits (0-30)
157 assert((offset >> 4) == 0); // offset on 4 bits (0-15)
158 assert((index >> 16) == 0); // index on 16 bits (0-65535)
159
160 return rawPrefix | (groupId << 25) | (modeId << 20) | (offset << 16) | index;
161}
162
164template<typename _EnumTy, int _groupId, int _modeId, PrefixValues _prefix = PrefixValues::generalKeys> struct KeyStore
165{
166 using EnumTy = _EnumTy;
167 static constexpr uint32_t groupId = _groupId < 0 ? noGroupIndex : _groupId;
168 static constexpr uint32_t modeId = _modeId < 0 ? noModeIndex : _modeId;
169 static constexpr PrefixValues prefix = _prefix;
170
171 // it's magic!
172 static constexpr uint16_t storeIdKey = 0xafff;
173
174 static_assert(sizeof(EnumTy) == sizeof(uint16_t), "uint16_t enum only");
175 static_assert((groupId >> 4) == 0, "Group index must fit on 4 bits!");
176 static_assert((modeId >> 5) == 0, "Mode index must fit on 5 bits!");
177
178 // \private maps to ContextTy::KeyProxy::setValue()
179 template<EnumTy key, typename T> static inline void LMBD_INLINE setValue(T value)
180 {
181 using valueTy = std::remove_cv_t<std::remove_reference_t<T>>;
182 constexpr uint16_t rawKey = (uint16_t)key;
183
184 static_assert(storeIdKey != rawKey, "error: key can not match storeIdKey (0xafff)");
185
186 // simple case: value is uint32_t, store it as-is
187 if constexpr (std::is_same_v<valueTy, uint32_t>)
188 {
189 constexpr auto idx = indexKeyFor(prefix, groupId, modeId, 0, rawKey);
191
192 // small case: value is smaller than uint32_t, store it on a uint32_t
193 }
194 else if constexpr (sizeof(valueTy) <= sizeof(uint32_t))
195 {
196 uint32_t storage = 0;
197 details::bit_cast<sizeof(value)>(storage, value);
198 setValue<key>(storage);
199
200 // large case: value is stored on up to 16 uint32_t
201 }
202 else if constexpr (sizeof(valueTy) <= 16 * sizeof(uint32_t))
203 {
204 constexpr uint8_t N = ((sizeof(valueTy) - 1) / sizeof(uint32_t)) + 1;
205 std::array<uint32_t, N> storage {};
206 details::bit_cast<sizeof(value)>(storage, value);
207 for (uint8_t I = 0; I < N; ++I)
208 {
209 uint32_t off = indexKeyFor(prefix, groupId, modeId, I, rawKey);
211 }
212 }
213 else
214 {
215 static_assert(sizeof(valueTy) <= 64, "KeyStore values limited to 64 bytes!");
216 }
217 }
218
219 // \private maps to ContextTy::KeyProxy::getValue()
220 template<EnumTy key, typename T> static inline bool LMBD_INLINE getValue(T& output)
221 {
222 constexpr uint16_t rawKey = (uint16_t)key;
223
224 static_assert(storeIdKey != rawKey, "error: key can not match storeIdKey (0xafff)");
225
226 // simple case: value is uint32_t, get it as-is
227 if constexpr (std::is_same_v<T, uint32_t>)
228 {
229 constexpr auto idx = indexKeyFor(prefix, groupId, modeId, 0, rawKey);
230 return physical::fileSystem::user::get_value(idx, output);
231
232 // small case: value is smaller than uint32_t, get it on a uint32_t
233 }
234 else if constexpr (sizeof(T) <= sizeof(uint32_t))
235 {
236 uint32_t storage = 0;
237 if (not getValue<key, uint32_t>(storage))
238 {
239 return false;
240 }
241
242 details::bit_cast<sizeof(output)>(output, storage);
243 return true;
244
245 // large case: value is stored on up to 16 uint32_t
246 }
247 else if constexpr (sizeof(T) <= 16 * sizeof(uint32_t))
248 {
249 constexpr uint8_t N = ((sizeof(T) - 1) / sizeof(uint32_t)) + 1;
250 std::array<uint32_t, N> storage {};
251 for (uint8_t I = 0; I < N; ++I)
252 {
253 uint32_t off = indexKeyFor(prefix, groupId, modeId, I, rawKey);
254 if (not physical::fileSystem::user::get_value(off, storage[I]))
255 {
256 return false;
257 }
258 }
259
260 details::bit_cast<sizeof(output)>(output, storage);
261 return true;
262 }
263 else
264 {
265 static_assert(sizeof(T) <= 64, "KeyStore values limited to 64 bytes!");
266 }
267 return false;
268 }
269
270 // \private maps to ContextTy::KeyProxy::getValue(defaultValue)
271 template<EnumTy key, typename T> static inline void LMBD_INLINE getValue(T& output, T defValue)
272 {
273 if (not getValue<key, T>(output))
274 {
275 output = defValue;
276 }
277 }
278
279 // \private maps to ContextTy::KeyProxy::hasValue
280 template<EnumTy key, typename T = uint32_t> static inline bool LMBD_INLINE hasValue()
281 {
282 T output;
283 return getValue<key, T>(output);
284 }
285
286 // \private empty store if \p storeId mismatch with value at \p storeIdKey
287 template<uint32_t storeId> static void migrateStoreIfNeeded()
288 {
289 constexpr auto idx = indexKeyFor(prefix, groupId, modeId, 0, storeIdKey);
290
291 // retrieve storeId from storage
292 uint32_t otherId = 0;
293 if (not physical::fileSystem::user::get_value(idx, otherId))
294 {
295 otherId = storeId;
297 }
298
299 // if it don't match our storeId, clean storage from our old keys
300 if (otherId != storeId || otherId == 0)
301 {
302 constexpr uint32_t select = 0xfff00000; // all but offset
303 constexpr uint32_t masked = idx & select;
306 }
307 }
308};
309
311template<uint32_t baseId, typename AllModes> static constexpr uint32_t derivateStoreIdImpl()
312{
313 constexpr uint32_t MixCstA = 0x8af8901d, MixCstB = 0x2f9c7c90;
314 constexpr uint8_t NbModes = std::tuple_size_v<AllModes>;
315
316 uint32_t storeId = baseId;
317 details::unroll<NbModes>([&](auto Idx) {
318 constexpr uint8_t I = decltype(Idx)::value;
319 using ModeHere = std::tuple_element_t<I, AllModes>;
320 using StoreHere = StoreEnumOf<ModeHere>;
321 constexpr bool hasStore = not std::is_same_v<StoreHere, NoStoreHere>;
322
323 uint32_t storeIdHere = 0;
324 if constexpr (hasStore)
325 {
326 storeIdHere = ModeHere::storeId;
327 }
328
329 // straightforward mix function
330 storeId += MixCstA;
331 storeId = (storeId << 7) ^ (storeId >> (32 - 7));
332 storeId ^= MixCstB;
333
334 storeId += storeIdHere;
335 });
336
337 return storeId;
338}
339
341template<uint32_t baseId, typename AllModes> static constexpr uint32_t derivateStoreId =
342 derivateStoreIdImpl<baseId, AllModes>();
343
344} // namespace lampda::modes::store
345
346#endif
Contains shorthand macro definitions.
Interface for the physical components of the file system.
Mode key store interface, see ContextTy::KeyProxy.
Definition: keystore.hpp:18
static void LMBD_INLINE setValue(const char(&key)[N], uint32_t value)
Set value for named key and read in in out.
Definition: keystore.hpp:55
static bool LMBD_INLINE getValue(const char(&key)[N], uint32_t &out)
Get value for named key and write it in out.
Definition: keystore.hpp:67
static void LMBD_INLINE migrateIfNeeded()
Check for migration and erase all values if needed IT WILL ERASE THE WHOLE MEMORY,...
Definition: keystore.hpp:81
static void clear_stored()
Force clear the stored parameters.
Definition: keystore.hpp:74
bool load_from_file()
Load system values from memory.
Definition: fileSystem.cpp:308
void write_to_file()
Write the system parameters to a file.
Definition: fileSystem.cpp:286
void write_to_file()
Write the user parameters to a file.
Definition: fileSystem.cpp:390
bool load_from_file()
Load user values from memory.
Definition: fileSystem.cpp:414
void set_value(const uint32_t key, const uint32_t value)
Store a key/value in the filesystem.
Definition: fileSystem.cpp:355
bool doKeyExists(const uint32_t key)
Return true if the given key exists in the filesystem.
Definition: fileSystem.cpp:328
uint32_t dropMatchingKeys(const uint32_t bitMatch, const uint32_t bitSelect)
Drop all keys using the given bit prefix.
Definition: fileSystem.cpp:364
bool get_value(const uint32_t key, uint32_t &value)
Check and return a value stored in a filesystem.
Definition: fileSystem.cpp:330
void clear()
clear the stored values in the currently loaded file system.
Definition: fileSystem.cpp:79
void clear_internal_fs()
hard clean of the whole filesystem, you will loose all stored data.
Definition: fileSystem.cpp:89
static constexpr uint32_t hash(const T s, const uint16_t maxSize=14, const uint16_t off=0)
Hash input string into a 32-bit unsigned integer.
Definition: utils.h:174
Define templated tools to analyze the manager objects.
Define useful functions.