libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
key_ops.hpp
1
25ErrorCode AddKeyBody(size_t name_len, size_t size, size_t& key_buf_offset)
26{
27 bool recycle = false;
28add_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
111ErrorCode 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
132ErrorCode 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
168ErrorCode 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() <
180 AlignSize(size) + AlignSize(sizeof(KeyInfo)) + 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 = {};
199 new_key.SetNameLength(key.GetNameLength());
200 new_key.SetDataSize(size);
201 WriteFlashOrExit(key_offset, new_key);
202 return AddKey(GetKeyName(key_offset), key.GetNameLength(), data, size);
203 }
204 return ErrorCode::OK;
205 }
206 }
207 return ErrorCode::FAILED;
208}
209
216size_t GetKeyData(size_t offset)
217{
218 KeyInfo key;
219 ReadFlashOrExit(offset, key);
220 return offset + AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength());
221}
222
229size_t GetKeyName(size_t offset) { return offset + AlignSize(sizeof(KeyInfo)); }
230
236size_t GetKeySize(size_t offset)
237{
238 KeyInfo key;
239 ReadFlashOrExit(offset, key);
240 return AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength()) +
241 AlignSize(key.GetDataSize());
242}
243
249size_t GetNextKey(size_t offset)
250{
251 KeyInfo key;
252 ReadFlashOrExit(offset, key);
253 return offset + GetKeySize(offset);
254}
255
262size_t GetLastKey(BlockType block)
263{
264 if (IsBlockEmpty(block))
265 {
266 return 0;
267 }
268
269 KeyInfo key;
270 size_t key_offset = GetBlockOffset(block) + LibXR::OffsetOf(&FlashInfo::key);
271 ReadFlashOrExit(key_offset, key);
273 {
274 key_offset = GetNextKey(key_offset);
275 ReadFlashOrExit(key_offset, key);
276 }
277 return key_offset;
278}
279
289bool KeyDataCompare(size_t offset, const void* data, size_t size)
290{
291 KeyInfo key;
292 ReadFlashOrExit(offset, key);
293 size_t key_data_offset = GetKeyData(offset);
294 uint8_t data_buffer = 0;
295 for (size_t i = 0; i < size; i++)
296 {
297 ReadFlashOrExit(key_data_offset + i, data_buffer);
298 if (data_buffer != (reinterpret_cast<const uint8_t*>(data))[i])
299 {
300 return true;
301 }
302 }
303 return false;
304}
305
314bool KeyNameCompare(size_t offset, const char* name)
315{
316 KeyInfo key;
317 ReadFlashOrExit(offset, key);
318 for (size_t i = 0; i < key.GetNameLength(); i++)
319 {
320 uint8_t data_buffer = 0;
321 ReadFlashOrExit(offset + AlignSize(sizeof(KeyInfo)) + i, data_buffer);
322 if (data_buffer != name[i])
323 {
324 return true;
325 }
326 }
327 return false;
328}
329
343size_t SearchKey(const char* name)
344{
345 if (IsBlockEmpty(BlockType::MAIN))
346 {
347 return 0;
348 }
349
350 KeyInfo key;
351 size_t key_offset = LibXR::OffsetOf(&FlashInfo::key);
352 ReadFlashOrExit(key_offset, key);
353
354 size_t ans = 0, need_cycle = 0;
355
356 while (true)
357 {
359 {
360 key_offset = GetNextKey(key_offset);
361 ReadFlashOrExit(key_offset, key);
362 need_cycle++;
363 continue;
364 }
365
366 if (!KeyNameCompare(key_offset, name))
367 {
368 ans = key_offset;
369 break;
370 }
371
373 {
374 break;
375 }
376
377 key_offset = GetNextKey(key_offset);
378 ReadFlashOrExit(key_offset, key);
379 }
380
381 if (need_cycle > recycle_threshold_)
382 {
383 Recycle();
384 return SearchKey(name);
385 }
386
387 return ans;
388}
读写对齐布尔位图块的工具 (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:98
Flash 存储的块信息结构 (Structure representing a Flash storage block).
Definition layout.hpp:164
KeyInfo key
Definition layout.hpp:186
uint32_t header
Flash 块头签名 / Flash block-header signature.
Definition layout.hpp:182
键信息结构,存储键的元数据 (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:154
void SetNameLength(uint8_t len)
设置键名长度 (Set the key name length).
Definition layout.hpp:130
BlockBoolData< MinWriteSize > no_next_key
是否是最后一个键
Definition layout.hpp:107
void SetDataSize(uint32_t size)
设置数据字节数 (Set the payload size in bytes).
Definition layout.hpp:145
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).
Definition layout.hpp:139