25ErrorCode 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);
111ErrorCode 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;
132ErrorCode 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;
168ErrorCode 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() <
185 return SetKey(name, data, size,
false);
190 return ErrorCode::FULL;
201 WriteFlashOrExit(key_offset, new_key);
202 return AddKey(GetKeyName(key_offset), key.
GetNameLength(), data, size);
204 return ErrorCode::OK;
207 return ErrorCode::FAILED;
216size_t GetKeyData(
size_t offset)
219 ReadFlashOrExit(offset, key);
229size_t GetKeyName(
size_t offset) {
return offset + AlignSize(
sizeof(
KeyInfo)); }
236size_t GetKeySize(
size_t offset)
239 ReadFlashOrExit(offset, key);
249size_t GetNextKey(
size_t offset)
252 ReadFlashOrExit(offset, key);
253 return offset + GetKeySize(offset);
262size_t GetLastKey(BlockType block)
264 if (IsBlockEmpty(block))
271 ReadFlashOrExit(key_offset, key);
274 key_offset = GetNextKey(key_offset);
275 ReadFlashOrExit(key_offset, key);
289bool KeyDataCompare(
size_t offset,
const void* data,
size_t size)
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++)
297 ReadFlashOrExit(key_data_offset + i, data_buffer);
298 if (data_buffer != (
reinterpret_cast<const uint8_t*
>(data))[i])
314bool KeyNameCompare(
size_t offset,
const char* name)
317 ReadFlashOrExit(offset, key);
320 uint8_t data_buffer = 0;
321 ReadFlashOrExit(offset + AlignSize(
sizeof(
KeyInfo)) + i, data_buffer);
322 if (data_buffer != name[i])
343size_t SearchKey(
const char* name)
345 if (IsBlockEmpty(BlockType::MAIN))
352 ReadFlashOrExit(key_offset, key);
354 size_t ans = 0, need_cycle = 0;
360 key_offset = GetNextKey(key_offset);
361 ReadFlashOrExit(key_offset, key);
366 if (!KeyNameCompare(key_offset, name))
377 key_offset = GetNextKey(key_offset);
378 ReadFlashOrExit(key_offset, key);
381 if (need_cycle > recycle_threshold_)
384 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).
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).