libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
database.cpp
1#include "database.hpp"
2
3#include <cstddef>
4#include <cstdint>
5
6#include "libxr_def.hpp"
7
8using namespace LibXR;
9
11 : flash_(flash), max_buffer_size_(max_buffer_size)
12{
13 ASSERT(flash.MinEraseSize() * 2 <= flash.Size());
14 if (max_buffer_size * 2 > flash.Size())
15 {
16 max_buffer_size = flash.Size() / 2;
17 }
18 auto block_num = static_cast<size_t>(flash.Size() / flash.MinEraseSize());
19 block_size_ = block_num / 2 * flash.MinEraseSize();
20 buffer_ = new uint8_t[max_buffer_size];
21
22 Init();
23}
24
26{
27 memset(buffer_, 0xFF, max_buffer_size_);
28 FlashInfo* flash_data_ = reinterpret_cast<FlashInfo*>(buffer_);
29 flash_data_->header = FLASH_HEADER;
30 flash_data_->key = {0, 0, 0};
32
34 {
35 InitBlock(BlockType::BACKUP);
36 }
37
39 {
41 {
42 InitBlock(BlockType::MAIN);
43 }
44 else
45 {
49 }
50 }
51
52 Load();
53}
54
63
65
67{
68 memset(buffer_, 0xFF, max_buffer_size_);
69 FlashInfo* flash_data_ = reinterpret_cast<FlashInfo*>(buffer_);
70 flash_data_->header = FLASH_HEADER;
71 flash_data_->key = {0, 0, 0};
75}
76
78{
79 auto ans = SearchKey(key.name_);
80 if (!ans)
81 {
82 return ErrorCode::NOT_FOUND;
83 }
84
85 KeyInfo key_buffer;
86 flash_.Read(ans, key_buffer);
87
88 if (key.raw_data_.size_ != key_buffer.GetDataSize())
89 {
90 return ErrorCode::FAILED;
91 }
92
93 GetKeyData(ans, key.raw_data_);
94
95 return ErrorCode::OK;
96}
97
98void DatabaseRawSequential::InitBlock(BlockType block)
99{
100 size_t offset = 0;
101 if (block == BlockType::BACKUP)
102 {
103 offset = block_size_;
104 }
105
106 flash_.Erase(offset, block_size_);
108}
109
117{
118 size_t offset = 0;
119 if (block == BlockType::BACKUP)
120 {
121 offset = block_size_;
122 }
123 FlashInfo flash_data_;
124 flash_.Read(offset, flash_data_);
125 return flash_data_.header == FLASH_HEADER;
126}
127
134{
135 size_t offset = 0;
136 if (block == BlockType::BACKUP)
137 {
138 offset = block_size_;
139 }
140 FlashInfo flash_data_;
141 flash_.Read(offset, flash_data_);
142 return flash_data_.key.GetNameLength() == 0;
143}
144
151{
152 size_t offset = 0;
153 if (block == BlockType::BACKUP)
154 {
155 offset = block_size_;
156 }
157 uint8_t checksum_byte = 0;
158 flash_.Read(offset + max_buffer_size_ / sizeof(CHECKSUM_BYTE) - 1, checksum_byte);
159 return checksum_byte != CHECKSUM_BYTE;
160}
161
162bool DatabaseRawSequential::HasLastKey(size_t offset)
163{
164 KeyInfo key;
165 flash_.Read(offset, key);
166 return key.GetNextKeyExist();
167}
168
169size_t DatabaseRawSequential::GetKeySize(size_t offset)
170{
171 KeyInfo key;
172 flash_.Read(offset, key);
173 return sizeof(KeyInfo) + key.GetNameLength() + key.GetDataSize();
174}
175
176size_t DatabaseRawSequential::GetNextKey(size_t offset)
177{
178 return offset + GetKeySize(offset);
179}
180
181size_t DatabaseRawSequential::GetLastKey(BlockType block)
182{
183 if (IsBlockEmpty(block))
184 {
185 return 0;
186 }
187
188 size_t offset = OFFSET_OF(FlashInfo, key);
189 while (HasLastKey(offset))
190 {
191 offset = GetNextKey(offset);
192 }
193 return offset;
194}
195
196void DatabaseRawSequential::SetNestKeyExist(size_t offset, bool exist)
197{
198 KeyInfo key;
199 flash_.Read(offset, key);
200 key.SetNextKeyExist(exist);
201 LibXR::Memory::FastCopy(buffer_ + offset, &key, sizeof(KeyInfo));
202}
203
204bool DatabaseRawSequential::KeyDataCompare(size_t offset, const void* data, size_t size)
205{
206 KeyInfo key;
207 flash_.Read(offset, key);
208 size_t key_data_offset = offset + sizeof(KeyInfo) + key.GetNameLength();
209 uint8_t data_buffer;
210 for (size_t i = 0; i < size; i++)
211 {
212 flash_.Read(key_data_offset + i, data_buffer);
213 if (data_buffer != ((uint8_t*)data)[i])
214 {
215 return true;
216 }
217 }
218 return false;
219}
220
221bool DatabaseRawSequential::KeyNameCompare(size_t offset, const char* name)
222{
223 KeyInfo key;
224 flash_.Read(offset, key);
225 for (size_t i = 0; i < key.GetNameLength(); i++)
226 {
227 uint8_t data_buffer;
228 flash_.Read(offset + sizeof(KeyInfo) + i, data_buffer);
229 if (data_buffer != name[i])
230 {
231 return true;
232 }
233 }
234 return false;
235}
236
237ErrorCode DatabaseRawSequential::AddKey(const char* name, const void* data, size_t size)
238{
239 if (auto ans = SearchKey(name))
240 {
241 return SetKey(ans, data, size);
242 }
243
244 const uint32_t NAME_LEN = strlen(name) + 1;
245 size_t last_key_offset = GetLastKey(BlockType::MAIN);
246 size_t key_buf_offset =
247 last_key_offset ? GetNextKey(last_key_offset) : OFFSET_OF(FlashInfo, key);
248
249 size_t end_pos_offset = key_buf_offset + sizeof(KeyInfo) + NAME_LEN + size;
250 if (end_pos_offset > max_buffer_size_ - 1)
251 {
252 return ErrorCode::FULL;
253 }
254
255 size_t data_ptr_offset = key_buf_offset + sizeof(KeyInfo);
256 LibXR::Memory::FastCopy(buffer_ + data_ptr_offset, name, NAME_LEN);
257 LibXR::Memory::FastCopy(buffer_ + data_ptr_offset + NAME_LEN, data, size);
258
259 KeyInfo key_buf = {0, static_cast<uint8_t>(NAME_LEN), static_cast<uint32_t>(size)};
260 LibXR::Memory::FastCopy(buffer_ + key_buf_offset, &key_buf, sizeof(KeyInfo));
261 if (last_key_offset)
262 {
263 SetNestKeyExist(last_key_offset, 1);
264 }
265
266 Save();
267 return ErrorCode::OK;
268}
269
270ErrorCode DatabaseRawSequential::SetKey(const char* name, const void* data, size_t size)
271{
272 if (size_t key_offset = SearchKey(name))
273 {
274 return SetKey(key_offset, data, size);
275 }
276 return ErrorCode::FAILED;
277}
278
279ErrorCode DatabaseRawSequential::SetKey(size_t offset, const void* data, size_t size)
280{
281 ASSERT(offset != 0);
282
283 KeyInfo key;
284 flash_.Read(offset, key);
285
286 if (key.GetDataSize() == size)
287 {
288 if (KeyDataCompare(offset, data, size))
289 {
290 LibXR::Memory::FastCopy(buffer_ + offset + sizeof(KeyInfo) + key.GetNameLength(),
291 data, size);
292 Save();
293 }
294 return ErrorCode::OK;
295 }
296
297 return ErrorCode::FAILED;
298}
299
300ErrorCode DatabaseRawSequential::GetKeyData(size_t offset, RawData data)
301{
302 KeyInfo key;
303 flash_.Read(offset, key);
304 if (key.GetDataSize() > data.size_)
305 {
306 return ErrorCode::FAILED;
307 }
308 auto data_offset = offset + sizeof(KeyInfo) + key.GetNameLength();
309 flash_.Read(data_offset, {data.addr_, key.GetDataSize()});
310 return ErrorCode::OK;
311}
312
313size_t DatabaseRawSequential::SearchKey(const char* name)
314{
316 {
317 return 0;
318 }
319
320 size_t key_offset = OFFSET_OF(FlashInfo, key);
321 while (true)
322 {
323 if (KeyNameCompare(key_offset, name) == 0)
324 {
325 return key_offset;
326 }
327 if (!HasLastKey(key_offset))
328 {
329 break;
330 }
331 key_offset = GetNextKey(key_offset);
332 }
333 return 0;
334}
键的基类,存储键名及其数据 (Base class for keys, storing key name and associated data).
Definition database.hpp:28
RawData raw_data_
原始数据 (Raw data associated with the key).
Definition database.hpp:31
const char * name_
键名 (Key name).
Definition database.hpp:30
void Save()
保存当前缓冲区内容到 Flash (Save the current buffer content to Flash).
Definition database.cpp:55
static constexpr uint8_t CHECKSUM_BYTE
校验字节 (Checksum byte).
Definition database.hpp:304
uint32_t max_buffer_size_
最大缓冲区大小 (Maximum buffer size).
Definition database.hpp:309
ErrorCode Get(Database::KeyBase &key) override
获取数据库中的键值 (Retrieve the key's value from the database).
Definition database.cpp:77
void Init()
初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).
Definition database.cpp:25
uint8_t * buffer_
数据缓冲区 (Data buffer).
Definition database.hpp:307
static constexpr uint32_t FLASH_HEADER
Flash 头部标识 (Flash header identifier).
Definition database.hpp:302
void Restore()
还原存储数据,清空 Flash 区域 (Restore storage data, clearing Flash memory area).
Definition database.cpp:66
bool IsBlockEmpty(BlockType block)
判断块是否为空 (Check if block is empty).
Definition database.cpp:133
uint32_t block_size_
Flash 块大小 (Flash block size).
Definition database.hpp:308
Flash & flash_
目标 Flash 存储设备 (Target Flash storage device).
Definition database.hpp:306
void Load()
从 Flash 加载数据到缓冲区 (Load data from Flash into the buffer).
Definition database.cpp:64
DatabaseRawSequential(Flash &flash, size_t max_buffer_size=256)
构造函数,初始化 Flash 存储和缓冲区 (Constructor initializing Flash storage and buffer).
Definition database.cpp:10
bool IsBlockInited(BlockType block)
判断块是否已初始化 (Check if block is initialized).
Definition database.cpp:116
@ BACKUP
备份块 (Backup block).
bool IsBlockError(BlockType block)
判断块是否损坏 (Check if block has an error).
Definition database.cpp:150
Abstract base class representing a flash memory interface. 抽象基类,表示闪存接口。
Definition flash.hpp:19
size_t Size() const
Returns the size of the flash memory area. 获取闪存存储区域的大小。
Definition flash.hpp:82
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. 从闪存中读取数据。
Definition flash.cpp:12
size_t MinEraseSize() const
Returns the minimum erasable block size in bytes. 获取最小可擦除块大小(字节)。
Definition flash.hpp:64
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:17
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
LibXR 命名空间
Definition ch32_gpio.hpp:9
Flash 存储的块信息结构 (Structure representing a Flash storage block).
Definition database.hpp:280
KeyInfo key
该块的键信息 (Key metadata in this block).
Definition database.hpp:282
uint32_t header
Flash 块头标识 (Flash block header identifier).
Definition database.hpp:281
键信息结构,存储键的元数据 (Structure containing key metadata).
Definition database.hpp:241