#include "common.hh" #include "str_buffer.hh" #include namespace { template 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 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 content_; size_t read_ptr_; size_t write_ptr_; }; } // namespace std::unique_ptr make_strbuffer(std::string content) { return std::make_unique>(std::move(content)); } std::unique_ptr make_strbuffer(std::string_view content) { return std::make_unique>(content); } std::unique_ptr make_strbuffer(std::shared_ptr content) { return std::make_unique(std::move(content)); }