25 ErrorCode AddKeyBody(
size_t name_len,
size_t size,
size_t& key_buf_offset)
29 size_t last_key_offset = GetLastKey(BlockType::MAIN);
33 AlignSize(
sizeof(
KeyInfo)) + AlignSize(name_len) + AlignSize(size))
45 return ErrorCode::FULL;
49 if (last_key_offset == 0)
52 flash_info.
header = FLASH_HEADER;
59 WriteFlashOrExit(0, flash_info);
64 key_buf_offset = GetNextKey(last_key_offset);
74 WriteFlashOrExit(key_buf_offset, new_key);
77 if (last_key_offset != 0)
80 ReadFlashOrExit(last_key_offset, last_key);
91 WriteFlashOrExit(last_key_offset, new_last_key);
94 WriteFlashOrExit(key_buf_offset, new_key);
111 ErrorCode AddKey(
size_t name_offset,
size_t name_len,
const void* data,
size_t size)
113 size_t key_buf_offset = 0;
114 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
115 if (ec != ErrorCode::OK)
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;
132 ErrorCode AddKey(
const char* name,
const void* data,
size_t size)
134 size_t name_len = strlen(name) + 1;
135 if (
auto ans = SearchKey(name))
137 return SetKey(name, data, size);
139 size_t key_buf_offset = 0;
140 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
141 if (ec != ErrorCode::OK)
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;
168 ErrorCode SetKey(
const char* name,
const void* data,
size_t size,
bool recycle =
true)
170 size_t key_offset = SearchKey(name);
174 ReadFlashOrExit(key_offset, key);
177 if (KeyDataCompare(key_offset, data, size))
179 if (AvailableSize() < AlignSize(size) + AlignSize(
sizeof(
KeyInfo)) +
185 return SetKey(name, data, size,
false);
190 return ErrorCode::FULL;
202 WriteFlashOrExit(key_offset, new_key);
203 return AddKey(GetKeyName(key_offset), key.
GetNameLength(), data, size);
205 return ErrorCode::OK;
208 return ErrorCode::FAILED;
217 size_t GetKeyData(
size_t offset)
220 ReadFlashOrExit(offset, key);
230 size_t GetKeyName(
size_t offset) {
return offset + AlignSize(
sizeof(
KeyInfo)); }
237 size_t GetKeySize(
size_t offset)
240 ReadFlashOrExit(offset, key);
250 size_t GetNextKey(
size_t offset)
253 ReadFlashOrExit(offset, key);
254 return offset + GetKeySize(offset);
263 size_t GetLastKey(BlockType block)
265 if (IsBlockEmpty(block))
272 ReadFlashOrExit(key_offset, key);
275 key_offset = GetNextKey(key_offset);
276 ReadFlashOrExit(key_offset, key);
290 bool KeyDataCompare(
size_t offset,
const void* data,
size_t size)
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++)
298 ReadFlashOrExit(key_data_offset + i, data_buffer);
299 if (data_buffer != (
reinterpret_cast<const uint8_t*
>(data))[i])
315 bool KeyNameCompare(
size_t offset,
const char* name)
318 ReadFlashOrExit(offset, key);
321 uint8_t data_buffer = 0;
322 ReadFlashOrExit(offset + AlignSize(
sizeof(
KeyInfo)) + i, data_buffer);
323 if (data_buffer != name[i])
344 size_t SearchKey(
const char* name)
346 if (IsBlockEmpty(BlockType::MAIN))
353 ReadFlashOrExit(key_offset, key);
355 size_t ans = 0, need_cycle = 0;
361 key_offset = GetNextKey(key_offset);
362 ReadFlashOrExit(key_offset, key);
367 if (!KeyNameCompare(key_offset, name))
378 key_offset = GetNextKey(key_offset);
379 ReadFlashOrExit(key_offset, key);
382 if (need_cycle > recycle_threshold_)
385 return SearchKey(name);
读写对齐布尔位图块的工具 (Helpers for reading and writing aligned boolean flag blocks).
static void SetFlag(BlockBoolData< BlockSize > &obj, bool value)
把一个布尔值编码进位图块 (Encode one boolean value into a flag block).
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量
Flash 存储的块信息结构 (Structure representing a Flash storage block).
KeyInfo key
紧跟在块头后的首个键头 / First key header stored right after the block header.
uint32_t header
Flash 块头签名 / Flash block-header signature.
键信息结构,存储键的元数据 (Structure containing key metadata).
BlockBoolData< MinWriteSize > uninit
该键是否未初始化
BlockBoolData< MinWriteSize > available_flag
该键是否有效
uint32_t GetDataSize() const
获取数据字节数 (Get the payload size in bytes).
void SetNameLength(uint8_t len)
设置键名长度 (Set the key name length).
BlockBoolData< MinWriteSize > no_next_key
是否是最后一个键
void SetDataSize(uint32_t size)
设置数据字节数 (Set the payload size in bytes).
uint8_t GetNameLength() const
获取键名长度 (Get the key name length).