1#include "raw_sequential.hpp"
6#include "libxr_def.hpp"
7#include "libxr_mem.hpp"
12 : flash_(flash), max_buffer_size_(max_buffer_size)
15 ASSERT(max_buffer_size <= flash.
Size() / 2);
18 buffer_ =
new uint8_t[max_buffer_size];
23DatabaseRawSequential::KeyInfo::KeyInfo() : raw_data(0xFFFFFFFF) {}
25DatabaseRawSequential::KeyInfo::KeyInfo(
bool nextKey, uint8_t nameLength,
29 SetNextKeyExist(nextKey);
30 SetNameLength(nameLength);
31 SetDataSize(dataSize);
34void DatabaseRawSequential::KeyInfo::SetNextKeyExist(
bool value)
36 raw_data = (raw_data & 0x7FFFFFFF) | (
static_cast<uint32_t
>(value & 0x1) << 31);
39bool DatabaseRawSequential::KeyInfo::GetNextKeyExist()
const
41 return (raw_data >> 31) & 0x1;
44void DatabaseRawSequential::KeyInfo::SetNameLength(uint8_t len)
46 raw_data = (raw_data & 0x80FFFFFF) | (
static_cast<uint32_t
>(len & 0x7F) << 24);
49uint8_t DatabaseRawSequential::KeyInfo::GetNameLength()
const
51 return (raw_data >> 24) & 0x7F;
54void DatabaseRawSequential::KeyInfo::SetDataSize(uint32_t size)
56 raw_data = (raw_data & 0xFF000000) | (size & 0x00FFFFFF);
59uint32_t DatabaseRawSequential::KeyInfo::GetDataSize()
const
61 return raw_data & 0x00FFFFFF;
64void DatabaseRawSequential::ReadFlashOrExit(
size_t offset,
RawData data)
66 [[maybe_unused]]
const auto flash_io_result = flash_.
Read(offset, data);
70void DatabaseRawSequential::WriteFlashOrExit(
size_t offset,
ConstRawData data)
72 [[maybe_unused]]
const auto flash_io_result = flash_.
Write(offset, data);
76void DatabaseRawSequential::EraseFlashOrExit(
size_t offset,
size_t size)
78 [[maybe_unused]]
const auto flash_io_result = flash_.
Erase(offset, size);
85 FlashInfo* flash_data_ =
reinterpret_cast<FlashInfo*
>(buffer_);
86 flash_data_->header = FLASH_HEADER;
87 flash_data_->key = {0, 0, 0};
88 buffer_[max_buffer_size_ - 1] = CHECKSUM_BYTE;
90 if (!IsBlockInited(BlockType::BACKUP) || IsBlockError(BlockType::BACKUP))
92 InitBlock(BlockType::BACKUP);
95 if (IsBlockError(BlockType::MAIN))
97 if (IsBlockEmpty(BlockType::BACKUP))
99 InitBlock(BlockType::MAIN);
103 ReadFlashOrExit(block_size_, {buffer_, max_buffer_size_});
104 EraseFlashOrExit(0, block_size_);
105 WriteFlashOrExit(0, {buffer_, max_buffer_size_});
114 EraseFlashOrExit(block_size_, block_size_);
115 WriteFlashOrExit(block_size_, {buffer_, max_buffer_size_});
117 EraseFlashOrExit(0, block_size_);
118 WriteFlashOrExit(0, {buffer_, max_buffer_size_});
126 FlashInfo* flash_data_ =
reinterpret_cast<FlashInfo*
>(buffer_);
127 flash_data_->header = FLASH_HEADER;
128 flash_data_->key = {0, 0, 0};
129 buffer_[max_buffer_size_ - 1] = CHECKSUM_BYTE;
130 EraseFlashOrExit(0, block_size_);
131 EraseFlashOrExit(block_size_, block_size_);
132 WriteFlashOrExit(0, {buffer_, max_buffer_size_});
133 WriteFlashOrExit(block_size_, {buffer_, max_buffer_size_});
138 auto ans = SearchKey(key.
name_);
145 ReadFlashOrExit(ans, key_buffer);
157void DatabaseRawSequential::InitBlock(BlockType block)
160 if (block == BlockType::BACKUP)
162 offset = block_size_;
165 EraseFlashOrExit(offset, block_size_);
166 WriteFlashOrExit(offset, {buffer_, max_buffer_size_});
175bool DatabaseRawSequential::IsBlockInited(BlockType block)
178 if (block == BlockType::BACKUP)
180 offset = block_size_;
183 ReadFlashOrExit(offset, flash_data_);
184 return flash_data_.
header == FLASH_HEADER;
192bool DatabaseRawSequential::IsBlockEmpty(BlockType block)
195 if (block == BlockType::BACKUP)
197 offset = block_size_;
200 ReadFlashOrExit(offset, flash_data_);
201 return flash_data_.
key.GetNameLength() == 0;
209bool DatabaseRawSequential::IsBlockError(BlockType block)
212 if (block == BlockType::BACKUP)
214 offset = block_size_;
216 uint8_t checksum_byte = 0;
217 ReadFlashOrExit(offset + max_buffer_size_ /
sizeof(CHECKSUM_BYTE) - 1, checksum_byte);
218 return checksum_byte != CHECKSUM_BYTE;
221bool DatabaseRawSequential::HasLastKey(
size_t offset)
224 ReadFlashOrExit(offset, key);
225 return key.GetNextKeyExist();
228size_t DatabaseRawSequential::GetKeySize(
size_t offset)
231 ReadFlashOrExit(offset, key);
235size_t DatabaseRawSequential::GetNextKey(
size_t offset)
237 return offset + GetKeySize(offset);
240size_t DatabaseRawSequential::GetLastKey(BlockType block)
242 if (IsBlockEmpty(block))
248 while (HasLastKey(offset))
250 offset = GetNextKey(offset);
255void DatabaseRawSequential::SetNestKeyExist(
size_t offset,
bool exist)
258 ReadFlashOrExit(offset, key);
259 key.SetNextKeyExist(exist);
263bool DatabaseRawSequential::KeyDataCompare(
size_t offset,
const void* data,
size_t size)
266 ReadFlashOrExit(offset, key);
269 for (
size_t i = 0; i < size; i++)
271 ReadFlashOrExit(key_data_offset + i, data_buffer);
272 if (data_buffer != ((uint8_t*)data)[i])
280bool DatabaseRawSequential::KeyNameCompare(
size_t offset,
const char* name)
283 ReadFlashOrExit(offset, key);
287 ReadFlashOrExit(offset +
sizeof(
KeyInfo) + i, data_buffer);
288 if (data_buffer != name[i])
296ErrorCode DatabaseRawSequential::AddKey(
const char* name,
const void* data,
size_t size)
298 if (
auto ans = SearchKey(name))
300 return SetKey(ans, data, size);
303 const uint32_t NAME_LEN = strlen(name) + 1;
304 size_t last_key_offset = GetLastKey(BlockType::MAIN);
305 size_t key_buf_offset =
308 size_t end_pos_offset = key_buf_offset +
sizeof(
KeyInfo) + NAME_LEN + size;
309 if (end_pos_offset > max_buffer_size_ - 1)
314 size_t data_ptr_offset = key_buf_offset +
sizeof(
KeyInfo);
318 KeyInfo key_buf = {0,
static_cast<uint8_t
>(NAME_LEN),
static_cast<uint32_t
>(size)};
322 SetNestKeyExist(last_key_offset, 1);
329ErrorCode DatabaseRawSequential::SetKey(
const char* name,
const void* data,
size_t size)
331 if (
size_t key_offset = SearchKey(name))
333 return SetKey(key_offset, data, size);
338ErrorCode DatabaseRawSequential::SetKey(
size_t offset,
const void* data,
size_t size)
340 DEV_ASSERT(offset != 0);
343 ReadFlashOrExit(offset, key);
347 if (KeyDataCompare(offset, data, size))
362 ReadFlashOrExit(offset, key);
372size_t DatabaseRawSequential::SearchKey(
const char* name)
374 if (IsBlockEmpty(BlockType::MAIN))
382 if (KeyNameCompare(key_offset, name) == 0)
386 if (!HasLastKey(key_offset))
390 key_offset = GetNextKey(key_offset);
只读原始数据视图 / Immutable raw data view
键的基类,存储键名及其数据 Base class for keys, storing key name and associated data.
RawData raw_data_
原始数据 / Raw data associated with the key.
const char * name_
键名 / Key name.
void Save()
保存当前缓冲区内容到 Flash Save the current buffer content to Flash.
ErrorCode Get(Database::KeyBase &key) override
获取数据库中的键值 Retrieve the key's value from the database.
void Init()
初始化数据库存储区,确保主备块正确 Initialize database storage, ensuring main and backup blocks are valid.
void Restore()
还原存储数据,清空 Flash 区域 Restore storage data, clearing Flash memory area.
void Load()
从 Flash 加载数据到缓冲区 Load data from Flash into the buffer.
DatabaseRawSequential(Flash &flash, size_t max_buffer_size=256)
构造函数,初始化 Flash 存储和缓冲区 Constructor initializing Flash storage and buffer.
抽象基类,表示闪存接口。 Abstract base class representing a flash memory interface.
size_t Size() const
获取闪存存储区域的大小 / Returns the size of the flash memory area.
virtual ErrorCode Erase(size_t offset, size_t size)=0
擦除闪存的指定区域 / Erases a section of the flash memory.
virtual ErrorCode Write(size_t offset, ConstRawData data)=0
向闪存写入数据 / Writes data to the flash memory.
virtual ErrorCode Read(size_t offset, RawData data)
从闪存中读取数据 / Reads data from the flash memory.
size_t MinEraseSize() const
获取最小可擦除块大小(字节)。 Returns the minimum erasable block size in bytes.
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
可写原始数据视图 / Mutable raw data view
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ NOT_FOUND
未找到 / Not found
@ FAILED
操作失败 / Operation failed
@ OK
操作成功 / Operation successful
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量 Computes the offset of a member within the owning object
Flash 存储的块信息结构 Structure representing a Flash storage block.
uint32_t header
Flash 块头签名 / Flash block-header signature.
键信息结构,存储键的元数据 Structure containing key metadata.
uint32_t GetDataSize() const
获取数据字节数 / Get the payload size in bytes.
uint8_t GetNameLength() const
获取键名长度 / Get the key name length.