328 0x12345678 + LIBXR_DATABASE_VERSION;
339 template <
size_t BlockSize>
342 uint8_t data[BlockSize];
346 template <
size_t BlockSize>
352 memset(obj.data, 0xFF, BlockSize);
355 obj.data[BlockSize - 1] &= 0xF0;
361 uint8_t last_4bits = obj.data[BlockSize - 1] & 0x0F;
362 return last_4bits == 0x0F;
372 for (
size_t i = 0; i < BlockSize - 1; ++i)
374 if (obj.data[i] != 0xFF)
380 uint8_t last_byte = obj.data[BlockSize - 1];
381 if ((last_byte & 0xF0) != 0xF0)
386 uint8_t last_4bits = last_byte & 0x0F;
387 if (!(last_4bits == 0x0F || last_4bits == 0x00))
417 void SetNameLength(uint8_t len)
422 uint8_t GetNameLength()
const {
return (
raw_info >> 25) & 0x7F; }
424 void SetDataSize(uint32_t size)
429 uint32_t GetDataSize()
const {
return raw_info & 0x01FFFFFF; }
443 memset(padding, 0xFF, MinWriteSize);
449 uint8_t padding[MinWriteSize];
471 ErrorCode AddKeyBody(
size_t name_len,
size_t size,
size_t& key_buf_offset)
473 bool recycle =
false;
478 if (last_key_offset == 0)
480 FlashInfo flash_info;
482 KeyInfo& tmp_key = flash_info.key;
483 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.no_next_key,
false);
484 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.available_flag,
false);
485 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.uninit,
false);
486 tmp_key.SetNameLength(0);
487 tmp_key.SetDataSize(0);
488 Write(0, flash_info);
489 key_buf_offset = GetNextKey(OFFSET_OF(FlashInfo, key));
493 key_buf_offset = GetNextKey(last_key_offset);
509 return ErrorCode::FULL;
513 KeyInfo new_key = {};
514 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.no_next_key,
true);
515 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag,
true);
516 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit,
true);
517 new_key.SetNameLength(name_len);
518 new_key.SetDataSize(size);
520 Write(key_buf_offset, new_key);
521 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit,
false);
523 if (last_key_offset != 0)
527 KeyInfo new_last_key = {};
528 BlockBoolUtil<MinWriteSize>::SetFlag(new_last_key.no_next_key,
false);
529 BlockBoolUtil<MinWriteSize>::SetFlag(
530 new_last_key.available_flag,
531 BlockBoolUtil<MinWriteSize>::ReadFlag(last_key.available_flag));
532 BlockBoolUtil<MinWriteSize>::SetFlag(
533 new_last_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(last_key.uninit));
534 new_last_key.SetNameLength(last_key.GetNameLength());
535 new_last_key.SetDataSize(last_key.GetDataSize());
537 Write(last_key_offset, new_last_key);
540 Write(key_buf_offset, new_key);
542 return ErrorCode::OK;
545 ErrorCode AddKey(
size_t name_offset,
size_t name_len,
const void* data,
size_t size)
547 size_t key_buf_offset = 0;
548 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
549 if (ec != ErrorCode::OK)
553 CopyFlashData(GetKeyName(key_buf_offset), name_offset, name_len);
554 Write(GetKeyData(key_buf_offset), {
reinterpret_cast<const uint8_t*
>(data), size});
555 return ErrorCode::OK;
558 ErrorCode AddKey(
const char* name,
const void* data,
size_t size)
560 size_t name_len = strlen(name) + 1;
561 if (
auto ans = SearchKey(name))
563 return SetKey(name, data, size);
565 size_t key_buf_offset = 0;
566 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
567 if (ec != ErrorCode::OK)
571 Write(GetKeyName(key_buf_offset), {
reinterpret_cast<const uint8_t*
>(name), name_len});
572 Write(GetKeyData(key_buf_offset), {
reinterpret_cast<const uint8_t*
>(data), size});
573 return ErrorCode::OK;
576 ErrorCode SetKeyCommon(
size_t key_offset,
size_t name_len,
const void* data,
583 if (key.GetDataSize() == size)
585 if (KeyDataCompare(key_offset, data, size))
587 KeyInfo new_key = {};
588 BlockBoolUtil<MinWriteSize>::SetFlag(
590 BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
591 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag,
false);
592 BlockBoolUtil<MinWriteSize>::SetFlag(
593 new_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit));
594 new_key.SetNameLength(name_len);
595 new_key.SetDataSize(size);
596 Write(key_offset, new_key);
597 return AddKey(GetKeyName(key_offset), name_len, data, size);
599 return ErrorCode::OK;
602 return ErrorCode::FAILED;
605 ErrorCode SetKey(
size_t name_offset,
size_t name_length,
const void* data,
size_t size)
607 size_t key_offset = SearchKey(name_offset, name_length);
608 return SetKeyCommon(key_offset, name_length, data, size);
611 ErrorCode SetKey(
const char* name,
const void* data,
size_t size,
bool recycle =
true)
613 size_t key_offset = SearchKey(name);
618 if (key.GetDataSize() == size)
620 if (KeyDataCompare(key_offset, data, size))
628 return SetKey(name, data, size,
false);
633 return ErrorCode::FULL;
636 KeyInfo new_key = {};
637 BlockBoolUtil<MinWriteSize>::SetFlag(
639 BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
640 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag,
false);
641 BlockBoolUtil<MinWriteSize>::SetFlag(
642 new_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit));
643 new_key.SetNameLength(key.GetNameLength());
644 new_key.SetDataSize(size);
645 Write(key_offset, new_key);
646 return AddKey(GetKeyName(key_offset), key.GetNameLength(), data, size);
648 return ErrorCode::OK;
651 return ErrorCode::FAILED;
654 size_t GetKeyData(
size_t offset)
661 size_t GetKeyName(
size_t offset) {
return offset +
AlignSize(
sizeof(KeyInfo)); }
674 KeyInfo& tmp_key = info.key;
675 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.no_next_key,
true);
676 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.available_flag,
true);
677 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.uninit,
false);
678 tmp_key.SetNameLength(0);
679 tmp_key.SetDataSize(0);
680 Write(offset, {
reinterpret_cast<uint8_t*
>(&info),
sizeof(FlashInfo)});
692 FlashInfo flash_data;
704 FlashInfo flash_data;
706 return BlockBoolUtil<MinWriteSize>::ReadFlag(flash_data.key.available_flag) ==
true;
716 uint32_t checksum = 0;
721 size_t GetKeySize(
size_t offset)
729 size_t GetNextKey(
size_t offset)
733 return offset + GetKeySize(offset);
738 if (IsBlockEmpty(block))
744 size_t key_offset = OFFSET_OF(FlashInfo, key);
750 while (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
752 key_offset = GetNextKey(key_offset);
758 bool KeyDataCompare(
size_t offset,
const void* data,
size_t size)
762 size_t key_data_offset = GetKeyData(offset);
763 uint8_t data_buffer = 0;
764 for (
size_t i = 0; i < size; i++)
766 flash_.
Read(key_data_offset + i, data_buffer);
767 if (data_buffer != (
reinterpret_cast<const uint8_t*
>(data))[i])
775 bool KeyNameCompare(
size_t offset,
const char* name)
779 for (
size_t i = 0; i < key.GetNameLength(); i++)
781 uint8_t data_buffer = 0;
783 if (data_buffer != name[i])
791 bool KeyNameCompare(
size_t offset_a,
size_t offset_b)
793 KeyInfo key_a, key_b;
796 if (key_a.GetNameLength() != key_b.GetNameLength())
800 for (
size_t i = 0; i < key_a.GetNameLength(); i++)
802 uint8_t data_buffer_a = 0, data_buffer_b = 0;
803 flash_.
Read(offset_a +
sizeof(KeyInfo) + i, data_buffer_a);
804 flash_.
Read(offset_b +
sizeof(KeyInfo) + i, data_buffer_b);
805 if (data_buffer_a != data_buffer_b)
813 void CopyFlashData(
size_t dst_offset,
size_t src_offset,
size_t size)
815 for (
size_t i = 0; i < size; i += MinWriteSize)
822 size_t SearchKey(
const char* name)
830 size_t key_offset = OFFSET_OF(FlashInfo, key);
833 size_t ans = 0, need_cycle = 0;
837 if (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.available_flag))
839 key_offset = GetNextKey(key_offset);
845 if (!KeyNameCompare(key_offset, name))
851 if (BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
856 key_offset = GetNextKey(key_offset);
863 return SearchKey(name);
877 return static_cast<size_t>((size + MinWriteSize - 1) / MinWriteSize) * MinWriteSize;
891 return ErrorCode::OK;
894 if (data.
size_ % MinWriteSize == 0)
900 auto final_block_index = data.
size_ - data.
size_ % MinWriteSize;
901 if (final_block_index != 0)
907 reinterpret_cast<const uint8_t*
>(data.
addr_) + final_block_index,
908 data.
size_ % MinWriteSize);
924 auto ans = SearchKey(key.
name_);
927 return ErrorCode::NOT_FOUND;
935 return ErrorCode::FAILED;
940 return ErrorCode::OK;
998 for (uint32_t i = 0; i <
block_size_; i += MinWriteSize)
1012 size_t key_offset = OFFSET_OF(
FlashInfo, key);
1014 size_t need_cycle = 0;
1017 key_offset = GetNextKey(key_offset);
1061 return ErrorCode::OK;
1065 size_t key_offset = OFFSET_OF(
FlashInfo, key);
1071 return ErrorCode::FAILED;
1080 Write(write_buff_offset, new_key);
1082 write_buff_offset += GetKeySize(write_buff_offset);
1086 key_offset = GetNextKey(key_offset);
1094 Write(write_buff_offset, key);
1096 CopyFlashData(write_buff_offset, GetKeyName(key_offset), key.GetNameLength());
1097 write_buff_offset +=
AlignSize(key.GetNameLength());
1098 CopyFlashData(write_buff_offset, GetKeyData(key_offset), key.GetDataSize());
1099 write_buff_offset +=
AlignSize(key.GetDataSize());
1103 for (uint32_t i = 0; i <
block_size_; i += MinWriteSize)
1111 return ErrorCode::OK;