libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
key_ops.hpp
1
25 ErrorCode AddKeyBody(size_t name_len, size_t size, size_t& key_buf_offset)
26 {
27 bool recycle = false;
28 add_again:
29 size_t last_key_offset = GetLastKey(BlockType::MAIN);
30 key_buf_offset = 0;
31
32 if (AvailableSize() <
33 AlignSize(sizeof(KeyInfo)) + AlignSize(name_len) + AlignSize(size))
34 {
35 if (!recycle)
36 {
37 Recycle();
38 recycle = true;
39 // NOLINTNEXTLINE
40 goto add_again;
41 }
42 else
43 {
44 ASSERT(false);
45 return ErrorCode::FULL;
46 }
47 }
48
49 if (last_key_offset == 0)
50 {
51 FlashInfo flash_info;
52 flash_info.header = FLASH_HEADER;
53 KeyInfo& tmp_key = flash_info.key;
57 tmp_key.SetNameLength(0);
58 tmp_key.SetDataSize(0);
59 WriteFlashOrExit(0, flash_info);
60 key_buf_offset = GetNextKey(LibXR::OffsetOf(&FlashInfo::key));
61 }
62 else
63 {
64 key_buf_offset = GetNextKey(last_key_offset);
65 }
66
67 KeyInfo new_key = {};
71 new_key.SetNameLength(name_len);
72 new_key.SetDataSize(size);
73
74 WriteFlashOrExit(key_buf_offset, new_key);
76
77 if (last_key_offset != 0)
78 {
79 KeyInfo last_key;
80 ReadFlashOrExit(last_key_offset, last_key);
81 KeyInfo new_last_key = {};
84 new_last_key.available_flag,
88 new_last_key.SetNameLength(last_key.GetNameLength());
89 new_last_key.SetDataSize(last_key.GetDataSize());
90
91 WriteFlashOrExit(last_key_offset, new_last_key);
92 }
93
94 WriteFlashOrExit(key_buf_offset, new_key);
95
96 return ErrorCode::OK;
97 }
98
111 ErrorCode AddKey(size_t name_offset, size_t name_len, const void* data, size_t size)
112 {
113 size_t key_buf_offset = 0;
114 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
115 if (ec != ErrorCode::OK)
116 {
117 return ec;
118 }
119 CopyFlashData(GetKeyName(key_buf_offset), name_offset, name_len);
120 WriteFlashOrExit(GetKeyData(key_buf_offset),
121 {reinterpret_cast<const uint8_t*>(data), size});
122 return ErrorCode::OK;
123 }
124
132 ErrorCode AddKey(const char* name, const void* data, size_t size)
133 {
134 size_t name_len = strlen(name) + 1;
135 if (auto ans = SearchKey(name))
136 {
137 return SetKey(name, data, size);
138 }
139 size_t key_buf_offset = 0;
140 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
141 if (ec != ErrorCode::OK)
142 {
143 return ec;
144 }
145 WriteFlashOrExit(GetKeyName(key_buf_offset),
146 {reinterpret_cast<const uint8_t*>(name), name_len});
147 WriteFlashOrExit(GetKeyData(key_buf_offset),
148 {reinterpret_cast<const uint8_t*>(data), size});
149 return ErrorCode::OK;
150 }
151
168 ErrorCode SetKey(const char* name, const void* data, size_t size, bool recycle = true)
169 {
170 size_t key_offset = SearchKey(name);
171 if (key_offset)
172 {
173 KeyInfo key;
174 ReadFlashOrExit(key_offset, key);
175 if (key.GetDataSize() == size)
176 {
177 if (KeyDataCompare(key_offset, data, size))
178 {
179 if (AvailableSize() < AlignSize(size) + AlignSize(sizeof(KeyInfo)) +
180 AlignSize(key.GetNameLength()))
181 {
182 if (recycle)
183 {
184 Recycle();
185 return SetKey(name, data, size, false);
186 }
187 else
188 {
189 ASSERT(false);
190 return ErrorCode::FULL;
191 }
192 }
193 KeyInfo new_key = {};
195 new_key.no_next_key,
200 new_key.SetNameLength(key.GetNameLength());
201 new_key.SetDataSize(size);
202 WriteFlashOrExit(key_offset, new_key);
203 return AddKey(GetKeyName(key_offset), key.GetNameLength(), data, size);
204 }
205 return ErrorCode::OK;
206 }
207 }
208 return ErrorCode::FAILED;
209 }
210
217 size_t GetKeyData(size_t offset)
218 {
219 KeyInfo key;
220 ReadFlashOrExit(offset, key);
221 return offset + AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength());
222 }
223
230 size_t GetKeyName(size_t offset) { return offset + AlignSize(sizeof(KeyInfo)); }
231
237 size_t GetKeySize(size_t offset)
238 {
239 KeyInfo key;
240 ReadFlashOrExit(offset, key);
241 return AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength()) +
242 AlignSize(key.GetDataSize());
243 }
244
250 size_t GetNextKey(size_t offset)
251 {
252 KeyInfo key;
253 ReadFlashOrExit(offset, key);
254 return offset + GetKeySize(offset);
255 }
256
263 size_t GetLastKey(BlockType block)
264 {
265 if (IsBlockEmpty(block))
266 {
267 return 0;
268 }
269
270 KeyInfo key;
271 size_t key_offset = GetBlockOffset(block) + LibXR::OffsetOf(&FlashInfo::key);
272 ReadFlashOrExit(key_offset, key);
274 {
275 key_offset = GetNextKey(key_offset);
276 ReadFlashOrExit(key_offset, key);
277 }
278 return key_offset;
279 }
280
290 bool KeyDataCompare(size_t offset, const void* data, size_t size)
291 {
292 KeyInfo key;
293 ReadFlashOrExit(offset, key);
294 size_t key_data_offset = GetKeyData(offset);
295 uint8_t data_buffer = 0;
296 for (size_t i = 0; i < size; i++)
297 {
298 ReadFlashOrExit(key_data_offset + i, data_buffer);
299 if (data_buffer != (reinterpret_cast<const uint8_t*>(data))[i])
300 {
301 return true;
302 }
303 }
304 return false;
305 }
306
315 bool KeyNameCompare(size_t offset, const char* name)
316 {
317 KeyInfo key;
318 ReadFlashOrExit(offset, key);
319 for (size_t i = 0; i < key.GetNameLength(); i++)
320 {
321 uint8_t data_buffer = 0;
322 ReadFlashOrExit(offset + AlignSize(sizeof(KeyInfo)) + i, data_buffer);
323 if (data_buffer != name[i])
324 {
325 return true;
326 }
327 }
328 return false;
329 }
330
344 size_t SearchKey(const char* name)
345 {
346 if (IsBlockEmpty(BlockType::MAIN))
347 {
348 return 0;
349 }
350
351 KeyInfo key;
352 size_t key_offset = LibXR::OffsetOf(&FlashInfo::key);
353 ReadFlashOrExit(key_offset, key);
354
355 size_t ans = 0, need_cycle = 0;
356
357 while (true)
358 {
360 {
361 key_offset = GetNextKey(key_offset);
362 ReadFlashOrExit(key_offset, key);
363 need_cycle++;
364 continue;
365 }
366
367 if (!KeyNameCompare(key_offset, name))
368 {
369 ans = key_offset;
370 break;
371 }
372
374 {
375 break;
376 }
377
378 key_offset = GetNextKey(key_offset);
379 ReadFlashOrExit(key_offset, key);
380 }
381
382 if (need_cycle > recycle_threshold_)
383 {
384 Recycle();
385 return SearchKey(name);
386 }
387
388 return ans;
389 }
读写对齐布尔位图块的工具 (Helpers for reading and writing aligned boolean flag blocks).
Definition layout.hpp:36
static void SetFlag(BlockBoolData< BlockSize > &obj, bool value)
把一个布尔值编码进位图块 (Encode one boolean value into a flag block).
Definition layout.hpp:43
ErrorCode
定义错误码枚举
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量
Definition libxr_def.hpp:88
Flash 存储的块信息结构 (Structure representing a Flash storage block).
Definition layout.hpp:163
KeyInfo key
紧跟在块头后的首个键头 / First key header stored right after the block header.
Definition layout.hpp:184
uint32_t header
Flash 块头签名 / Flash block-header signature.
Definition layout.hpp:181
键信息结构,存储键的元数据 (Structure containing key metadata).
Definition layout.hpp:106
BlockBoolData< MinWriteSize > uninit
该键是否未初始化
Definition layout.hpp:109
BlockBoolData< MinWriteSize > available_flag
该键是否有效
Definition layout.hpp:108
uint32_t GetDataSize() const
获取数据字节数 (Get the payload size in bytes).
Definition layout.hpp:153
void SetNameLength(uint8_t len)
设置键名长度 (Set the key name length).
Definition layout.hpp:129
BlockBoolData< MinWriteSize > no_next_key
是否是最后一个键
Definition layout.hpp:107
void SetDataSize(uint32_t size)
设置数据字节数 (Set the payload size in bytes).
Definition layout.hpp:144
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).
Definition layout.hpp:138