diff --git a/include/dwarfs/byte_buffer.h b/include/dwarfs/byte_buffer.h index e335e314..7ce20fc4 100644 --- a/include/dwarfs/byte_buffer.h +++ b/include/dwarfs/byte_buffer.h @@ -78,6 +78,8 @@ class mutable_byte_buffer_interface : public byte_buffer_interface { // that would reallocate the buffer will throw. virtual void freeze_location() = 0; + virtual void append(void const* data, size_t size) = 0; + virtual internal::malloc_buffer& raw_buffer() = 0; }; @@ -168,6 +170,13 @@ class mutable_byte_buffer { void freeze_location() { bb_->freeze_location(); } + void append(void const* data, size_t size) { bb_->append(data, size); } + + template + void append(T const& data) { + append(data.data(), data.size()); + } + internal::malloc_buffer& raw_buffer() { return bb_->raw_buffer(); } void swap(mutable_byte_buffer& other) noexcept { std::swap(bb_, other.bb_); } diff --git a/src/malloc_byte_buffer.cpp b/src/malloc_byte_buffer.cpp index 76eb3862..55d4ab3a 100644 --- a/src/malloc_byte_buffer.cpp +++ b/src/malloc_byte_buffer.cpp @@ -94,6 +94,13 @@ class malloc_byte_buffer_impl : public mutable_byte_buffer_interface { frozen_.store(true, std::memory_order_release); } + void append(void const* data, size_t size) override { + if (frozen() && data_.size() + size > data_.capacity()) { + frozen_error("append beyond capacity"); + } + data_.append(data, size); + } + internal::malloc_buffer& raw_buffer() override { return data_; } private: diff --git a/src/reader/block_cache_byte_buffer_factory.cpp b/src/reader/block_cache_byte_buffer_factory.cpp index 53f5d7a0..bd498d94 100644 --- a/src/reader/block_cache_byte_buffer_factory.cpp +++ b/src/reader/block_cache_byte_buffer_factory.cpp @@ -27,6 +27,7 @@ */ #include +#include #include #include @@ -138,6 +139,14 @@ class mmap_byte_buffer_impl : public mutable_byte_buffer_interface { // always frozen } + void append(void const* data, size_t size) override { + if (size_ + size > data_.size()) { + frozen_error("append beyond capacity"); + } + std::memcpy(data_.data() + size_, data, size); + size_ += size; + } + internal::malloc_buffer& raw_buffer() override { throw std::runtime_error( "operation not allowed on mmap buffer: raw_buffer");