X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fio%2FLineBuffer.hpp;fp=src%2Fio%2FLineBuffer.hpp;h=4fcc3ca0e81127e0131bd5a788f811b79d5af5ad;hb=fd86376a8e7d3f1b09be3d018f772ef884937238;hp=0000000000000000000000000000000000000000;hpb=ca74cd8cdaf25b5ae778bef1dbabad21cea13b2d;p=blank.git diff --git a/src/io/LineBuffer.hpp b/src/io/LineBuffer.hpp new file mode 100644 index 0000000..4fcc3ca --- /dev/null +++ b/src/io/LineBuffer.hpp @@ -0,0 +1,71 @@ +#ifndef BLANK_IO_LINEBUFFER_HPP_ +#define BLANK_IO_LINEBUFFER_HPP_ + +#include +#include +#include + + +namespace blank { + +template +class LineBuffer { + +public: + explicit LineBuffer(char term = '\n') noexcept + : buffer{0} + , term(term) + , head(buffer) { } + + char *begin() noexcept { + return buffer; + } + const char *begin() const noexcept { + return buffer; + } + char *end() noexcept { + return head; + } + const char *end() const noexcept { + return head; + } + + /// extract one line from the buffer, terminator not included + /// @return false if the buffer does not contain a complete line + bool Extract(std::string &line) { + char *line_end = std::find(begin(), end(), term); + if (line_end == end()) { + return false; + } + line.assign(begin(), line_end); + ++line_end; + std::move(line_end, end(), begin()); + return true; + } + + /// get a pointer to append data to the buffer + /// it is safe to write at most Remain() bytes + char *WriteHead() noexcept { + return head; + } + + // call when data has been written to WriteHead() + void Update(std::size_t written) { + assert(written <= Remain()); + head += written; + } + + std::size_t Remain() const noexcept { + return std::distance(end(), buffer + size); + } + +private: + char buffer[size]; + char term; + char *head; + +}; + +} + +#endif