#include "text_buffer.h" #include namespace roro::gemini { void TextBuffer::append(const char* data, size_t len) { bytes_ += len; for (size_t i = 0; i < len; i++) { if (data[i] == '\n') endLine(); else partial_ += data[i]; } } void TextBuffer::finish() { if (!partial_.empty()) endLine(); } void TextBuffer::endLine() { if (!partial_.empty() && partial_.back() == '\r') partial_.pop_back(); size_t len = std::min(partial_.size(), 0xFFFF); // A line never spans two chunks: a new chunk when it doesn't fit (bigger if the line is). if (chunks_.empty() || chunks_.back().size() + len > chunks_.back().capacity()) { chunks_.emplace_back(); chunks_.back().reserve(std::max(kChunk, len)); } std::string& chunk = chunks_.back(); lines_.push_back({static_cast(chunks_.size() - 1), static_cast(chunk.size()), static_cast(len)}); chunk.append(partial_, 0, len); partial_.clear(); } std::string TextBuffer::line(size_t i) const { if (i >= lines_.size()) return ""; const Ref& r = lines_[i]; return chunks_[r.chunk].substr(r.offset, r.length); } void TextBuffer::clear() { chunks_.clear(); lines_.clear(); partial_.clear(); bytes_ = 0; } } // namespace roro::gemini