| 728 | } |
| 729 | |
| 730 | static bit_vector deserialize(const std::vector<uint8_t>& buffer) |
| 731 | { |
| 732 | // Check if buffer is large enough to contain the size_t header |
| 733 | if (buffer.size() < sizeof(size_t)) { |
| 734 | throw exception("Buffer too small to contain bit_vector header"); |
| 735 | } |
| 736 | |
| 737 | size_t size; |
| 738 | std::memcpy(&size, buffer.data(), sizeof(size_t)); |
| 739 | |
| 740 | bit_vector result(size); |
| 741 | size_t blocks_size = (buffer.size() - sizeof(size_t)) / sizeof(block_type); |
| 742 | |
| 743 | // Only copy data if there are blocks to copy and the buffer is large enough |
| 744 | if (blocks_size > 0 && !result.blocks_.empty()) { |
| 745 | // Validate that the buffer contains enough data for the calculated blocks |
| 746 | size_t expected_buffer_size = sizeof(size_t) + blocks_size * sizeof(block_type); |
| 747 | if (buffer.size() < expected_buffer_size) { |
| 748 | throw std::runtime_error("Buffer too small for bit_vector data"); |
| 749 | } |
| 750 | |
| 751 | std::memcpy(result.blocks_.data(), buffer.data() + sizeof(size_t), blocks_size * sizeof(block_type)); |
| 752 | } |
| 753 | |
| 754 | return result; |
| 755 | } |
| 756 | |
| 757 | // Direct access to underlying data for advanced operations |
| 758 | const block_type* data() const |