diff options
Diffstat (limited to 'src/str_buffer.cc')
| -rw-r--r-- | src/str_buffer.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/str_buffer.cc b/src/str_buffer.cc new file mode 100644 index 0000000..6771cad --- /dev/null +++ b/src/str_buffer.cc @@ -0,0 +1,92 @@ +#include "common.hh" + +#include "str_buffer.hh" + +#include <utility> + +namespace { + +template<typename T> +class StringBuffer : public RoBuffer { +public: + explicit StringBuffer(T str) + : str_(std::move(str)), offset_(0) {} + + bool empty() const override { + return offset_ >= str_.size(); + } + + char const* rbuf(size_t /* want */, size_t& avail) override { + avail = str_.size() - offset_; + return str_.data() + offset_; + } + + void rcommit(size_t bytes) override { + assert(str_.size() - offset_ >= bytes); + offset_ += bytes; + } + +private: + T str_; + size_t offset_; +}; + +class SharedStringBuffer : public Buffer { +public: + explicit SharedStringBuffer(std::shared_ptr<std::string> content) + : content_(std::move(content)), read_ptr_(0), write_ptr_(content_->size()) { + } + + bool empty() const override { + return read_ptr_ >= content_->size(); + } + + char const* rbuf(size_t /* want */, size_t& avail) override { + avail = content_->size() - read_ptr_; + return content_->data() + read_ptr_; + } + + void rcommit(size_t bytes) override { + assert(content_->size() - read_ptr_ >= bytes); + read_ptr_ += bytes; + } + + bool full() const override { + return false; + } + + void clear() override { + content_->clear(); + read_ptr_ = write_ptr_ = 0; + } + + char* wbuf(size_t request, size_t& avail) override { + avail = request; + content_->resize(write_ptr_ + request); + return content_->data() + write_ptr_; + } + + void wcommit(size_t bytes) override { + assert(content_->size() - write_ptr_ >= bytes); + write_ptr_ += bytes; + } + +private: + std::shared_ptr<std::string> content_; + size_t read_ptr_; + size_t write_ptr_; +}; + +} // namespace + +std::unique_ptr<RoBuffer> make_strbuffer(std::string content) { + return std::make_unique<StringBuffer<std::string>>(std::move(content)); +} + +std::unique_ptr<RoBuffer> make_strbuffer(std::string_view content) { + return std::make_unique<StringBuffer<std::string_view>>(content); +} + +std::unique_ptr<Buffer> make_strbuffer(std::shared_ptr<std::string> content) { + return std::make_unique<SharedStringBuffer>(std::move(content)); +} |
