331 0x12345678 + LIBXR_DATABASE_VERSION;
342 template <
size_t BlockSize>
345 uint8_t data[BlockSize];
349 template <
size_t BlockSize>
355 memset(obj.data, 0xFF, BlockSize);
358 obj.data[BlockSize - 1] &= 0xF0;
364 uint8_t last_4bits = obj.data[BlockSize - 1] & 0x0F;
365 return last_4bits == 0x0F;
375 for (
size_t i = 0; i < BlockSize - 1; ++i)
377 if (obj.data[i] != 0xFF)
383 uint8_t last_byte = obj.data[BlockSize - 1];
384 if ((last_byte & 0xF0) != 0xF0)
389 uint8_t last_4bits = last_byte & 0x0F;
390 if (!(last_4bits == 0x0F || last_4bits == 0x00))
420 void SetNameLength(uint8_t len)
425 uint8_t GetNameLength()
const {
return (
raw_info >> 25) & 0x7F; }
427 void SetDataSize(uint32_t size)
432 uint32_t GetDataSize()
const {
return raw_info & 0x01FFFFFF; }
446 memset(padding, 0xFF, MinWriteSize);
452 uint8_t padding[MinWriteSize];
474 ErrorCode AddKeyBody(
size_t name_len,
size_t size,
size_t& key_buf_offset)
476 bool recycle =
false;
494 return ErrorCode::FULL;
498 if (last_key_offset == 0)
500 FlashInfo flash_info;
502 KeyInfo& tmp_key = flash_info.key;
503 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.no_next_key,
false);
504 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.available_flag,
false);
505 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.uninit,
false);
506 tmp_key.SetNameLength(0);
507 tmp_key.SetDataSize(0);
508 Write(0, flash_info);
509 key_buf_offset = GetNextKey(OFFSET_OF(FlashInfo, key));
513 key_buf_offset = GetNextKey(last_key_offset);
516 KeyInfo new_key = {};
517 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.no_next_key,
true);
518 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag,
true);
519 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit,
true);
520 new_key.SetNameLength(name_len);
521 new_key.SetDataSize(size);
523 Write(key_buf_offset, new_key);
524 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit,
false);
526 if (last_key_offset != 0)
530 KeyInfo new_last_key = {};
531 BlockBoolUtil<MinWriteSize>::SetFlag(new_last_key.no_next_key,
false);
532 BlockBoolUtil<MinWriteSize>::SetFlag(
533 new_last_key.available_flag,
534 BlockBoolUtil<MinWriteSize>::ReadFlag(last_key.available_flag));
535 BlockBoolUtil<MinWriteSize>::SetFlag(
536 new_last_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(last_key.uninit));
537 new_last_key.SetNameLength(last_key.GetNameLength());
538 new_last_key.SetDataSize(last_key.GetDataSize());
540 Write(last_key_offset, new_last_key);
543 Write(key_buf_offset, new_key);
545 return ErrorCode::OK;
548 ErrorCode AddKey(
size_t name_offset,
size_t name_len,
const void* data,
size_t size)
550 size_t key_buf_offset = 0;
551 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
552 if (ec != ErrorCode::OK)
556 CopyFlashData(GetKeyName(key_buf_offset), name_offset, name_len);
557 Write(GetKeyData(key_buf_offset), {
reinterpret_cast<const uint8_t*
>(data), size});
558 return ErrorCode::OK;
561 ErrorCode AddKey(
const char* name,
const void* data,
size_t size)
563 size_t name_len = strlen(name) + 1;
564 if (
auto ans = SearchKey(name))
566 return SetKey(name, data, size);
568 size_t key_buf_offset = 0;
569 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
570 if (ec != ErrorCode::OK)
574 Write(GetKeyName(key_buf_offset), {
reinterpret_cast<const uint8_t*
>(name), name_len});
575 Write(GetKeyData(key_buf_offset), {
reinterpret_cast<const uint8_t*
>(data), size});
576 return ErrorCode::OK;
579 ErrorCode SetKeyCommon(
size_t key_offset,
size_t name_len,
const void* data,
586 if (key.GetDataSize() == size)
588 if (KeyDataCompare(key_offset, data, size))
590 KeyInfo new_key = {};
591 BlockBoolUtil<MinWriteSize>::SetFlag(
593 BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
594 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag,
false);
595 BlockBoolUtil<MinWriteSize>::SetFlag(
596 new_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit));
597 new_key.SetNameLength(name_len);
598 new_key.SetDataSize(size);
599 Write(key_offset, new_key);
600 return AddKey(GetKeyName(key_offset), name_len, data, size);
602 return ErrorCode::OK;
605 return ErrorCode::FAILED;
608 ErrorCode SetKey(
size_t name_offset,
size_t name_length,
const void* data,
size_t size)
610 size_t key_offset = SearchKey(name_offset, name_length);
611 return SetKeyCommon(key_offset, name_length, data, size);
614 ErrorCode SetKey(
const char* name,
const void* data,
size_t size,
bool recycle =
true)
616 size_t key_offset = SearchKey(name);
621 if (key.GetDataSize() == size)
623 if (KeyDataCompare(key_offset, data, size))
631 return SetKey(name, data, size,
false);
636 return ErrorCode::FULL;
639 KeyInfo new_key = {};
640 BlockBoolUtil<MinWriteSize>::SetFlag(
642 BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
643 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag,
false);
644 BlockBoolUtil<MinWriteSize>::SetFlag(
645 new_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit));
646 new_key.SetNameLength(key.GetNameLength());
647 new_key.SetDataSize(size);
648 Write(key_offset, new_key);
649 return AddKey(GetKeyName(key_offset), key.GetNameLength(), data, size);
651 return ErrorCode::OK;
654 return ErrorCode::FAILED;
657 size_t GetKeyData(
size_t offset)
664 size_t GetKeyName(
size_t offset) {
return offset +
AlignSize(
sizeof(KeyInfo)); }
677 KeyInfo& tmp_key = info.key;
678 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.no_next_key,
true);
679 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.available_flag,
true);
680 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.uninit,
false);
681 tmp_key.SetNameLength(0);
682 tmp_key.SetDataSize(0);
683 Write(offset, {
reinterpret_cast<uint8_t*
>(&info),
sizeof(FlashInfo)});
695 FlashInfo flash_data;
707 FlashInfo flash_data;
709 return BlockBoolUtil<MinWriteSize>::ReadFlag(flash_data.key.available_flag) ==
true;
719 uint32_t checksum = 0;
724 size_t GetKeySize(
size_t offset)
732 size_t GetNextKey(
size_t offset)
736 return offset + GetKeySize(offset);
741 if (IsBlockEmpty(block))
747 size_t key_offset = OFFSET_OF(FlashInfo, key);
753 while (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
755 key_offset = GetNextKey(key_offset);
761 bool KeyDataCompare(
size_t offset,
const void* data,
size_t size)
765 size_t key_data_offset = GetKeyData(offset);
766 uint8_t data_buffer = 0;
767 for (
size_t i = 0; i < size; i++)
769 flash_.
Read(key_data_offset + i, data_buffer);
770 if (data_buffer != (
reinterpret_cast<const uint8_t*
>(data))[i])
778 bool KeyNameCompare(
size_t offset,
const char* name)
782 for (
size_t i = 0; i < key.GetNameLength(); i++)
784 uint8_t data_buffer = 0;
786 if (data_buffer != name[i])
794 bool KeyNameCompare(
size_t offset_a,
size_t offset_b)
796 KeyInfo key_a, key_b;
799 if (key_a.GetNameLength() != key_b.GetNameLength())
803 for (
size_t i = 0; i < key_a.GetNameLength(); i++)
805 uint8_t data_buffer_a = 0, data_buffer_b = 0;
806 flash_.
Read(offset_a +
sizeof(KeyInfo) + i, data_buffer_a);
807 flash_.
Read(offset_b +
sizeof(KeyInfo) + i, data_buffer_b);
808 if (data_buffer_a != data_buffer_b)
816 void CopyFlashData(
size_t dst_offset,
size_t src_offset,
size_t size)
818 for (
size_t i = 0; i < size; i += MinWriteSize)
825 size_t SearchKey(
const char* name)
833 size_t key_offset = OFFSET_OF(FlashInfo, key);
836 size_t ans = 0, need_cycle = 0;
840 if (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.available_flag))
842 key_offset = GetNextKey(key_offset);
848 if (!KeyNameCompare(key_offset, name))
854 if (BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
859 key_offset = GetNextKey(key_offset);
866 return SearchKey(name);
880 return static_cast<size_t>((size + MinWriteSize - 1) / MinWriteSize) * MinWriteSize;
894 return ErrorCode::OK;
897 if (data.
size_ % MinWriteSize == 0)
903 auto final_block_index = data.
size_ - data.
size_ % MinWriteSize;
904 if (final_block_index != 0)
911 data.
size_ % MinWriteSize);
927 auto ans = SearchKey(key.
name_);
930 return ErrorCode::NOT_FOUND;
938 return ErrorCode::FAILED;
943 return ErrorCode::OK;
1001 for (uint32_t i = 0; i <
block_size_; i += MinWriteSize)
1015 size_t key_offset = OFFSET_OF(
FlashInfo, key);
1017 size_t need_cycle = 0;
1020 key_offset = GetNextKey(key_offset);
1022 if (key_offset +
sizeof(key) >=
flash_.
Size())
1072 return ErrorCode::OK;
1076 size_t key_offset = OFFSET_OF(
FlashInfo, key);
1090 Write(write_buff_offset, new_key);
1092 write_buff_offset += GetKeySize(write_buff_offset);
1096 key_offset = GetNextKey(key_offset);
1104 Write(write_buff_offset, key);
1106 CopyFlashData(write_buff_offset, GetKeyName(key_offset), key.GetNameLength());
1107 write_buff_offset +=
AlignSize(key.GetNameLength());
1108 CopyFlashData(write_buff_offset, GetKeyData(key_offset), key.GetDataSize());
1109 write_buff_offset +=
AlignSize(key.GetDataSize());
1113 for (uint32_t i = 0; i <
block_size_; i += MinWriteSize)
1121 return ErrorCode::OK;