summaryrefslogtreecommitdiff
path: root/src/data_buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/data_buffer.cpp')
-rw-r--r--src/data_buffer.cpp36
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;
+}