diff --git a/src/fs/io/BufferedReader.cxx b/src/fs/io/BufferedReader.cxx index a8c919048..dac092b17 100644 --- a/src/fs/io/BufferedReader.cxx +++ b/src/fs/io/BufferedReader.cxx @@ -22,6 +22,11 @@ #include "Reader.hxx" #include "util/TextFile.hxx" +#include + +#include +#include + bool BufferedReader::Fill(bool need_more) { @@ -48,6 +53,32 @@ BufferedReader::Fill(bool need_more) return true; } +size_t +BufferedReader::ReadFromBuffer(WritableBuffer dest) +{ + auto src = Read(); + size_t nbytes = std::min(src.size, dest.size); + memcpy(dest.data, src.data, nbytes); + return nbytes; +} + +void +BufferedReader::ReadFull(WritableBuffer _dest) +{ + auto dest = WritableBuffer::FromVoid(_dest); + assert(dest.size == _dest.size); + + while (true) { + size_t nbytes = ReadFromBuffer(dest.ToVoid()); + dest.skip_front(nbytes); + if (dest.size == 0) + break; + + if (!Fill(true)) + throw std::runtime_error("Premature end of file"); + } +} + char * BufferedReader::ReadLine() { diff --git a/src/fs/io/BufferedReader.hxx b/src/fs/io/BufferedReader.hxx index 4bc40f236..6d6bd5431 100644 --- a/src/fs/io/BufferedReader.hxx +++ b/src/fs/io/BufferedReader.hxx @@ -55,6 +55,19 @@ public: buffer.Consume(n); } + /** + * Read (and consume) data from the input buffer into the + * given buffer. Does not attempt to refill the buffer. + */ + size_t ReadFromBuffer(WritableBuffer dest); + + /** + * Read data into the given buffer and consume it from our + * buffer. Throw an exception if the request cannot be + * forfilled. + */ + void ReadFull(WritableBuffer dest); + char *ReadLine(); unsigned GetLineNumber() const {