diff options
Diffstat (limited to 'src/data_buffer.cpp')
-rw-r--r-- | src/data_buffer.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/data_buffer.cpp b/src/data_buffer.cpp index 33cb0b3..c4c1d8b 100644 --- a/src/data_buffer.cpp +++ b/src/data_buffer.cpp @@ -4,6 +4,8 @@ #include "data_buffer.h" #include <cassert> +#include <cerrno> +#include <cstdlib> #include <cstring> void DataBuffer::Expand(size_t new_size) @@ -27,3 +29,37 @@ DataBuffer::~DataBuffer() buffer_size = 0; occupied_size = 0; } + +DataBuffer DataBuffer::FromStream(FILE *stream) +{ + DataBuffer db{}; + assert(db.buffer && db.buffer_size >= db.kInitialSize); + while (1) { + const size_t read_size = db.buffer_size - db.occupied_size; + const size_t fread_ret = fread( + db.buffer + db.occupied_size, sizeof(*db.buffer), read_size, stream); + db.occupied_size += fread_ret; + if (fread_ret >= db.buffer_size) { + assert(fread_ret == db.buffer_size); + db.Expand(db.buffer_size * 2); + } else { + const int err = errno; + if (feof(stream)) { + break; + } else if (ferror(stream)) { + fprintf( + stderr, + "DataBuffer::FromStream: fread(%zu): " + "Error (%d): \"%s\"\n", + read_size, + err, + strerror(err)); + } else if (db.buffer_size == db.occupied_size) { + db.Expand(db.buffer_size * 2); + } else { + assert(false); + } + } + } + return db; +} |