From 1709ab6810486648ac23bcf683d4e2326ede9d5a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 17 Feb 2014 23:04:06 +0100 Subject: fs/TextFile: use custom allocation instead of GString --- src/fs/TextFile.cxx | 48 ++++++++++++++++++++++++++---------------------- src/fs/TextFile.hxx | 5 +++-- 2 files changed, 29 insertions(+), 24 deletions(-) (limited to 'src/fs') diff --git a/src/fs/TextFile.cxx b/src/fs/TextFile.cxx index 21bd8ee8f..b1a92b9cc 100644 --- a/src/fs/TextFile.cxx +++ b/src/fs/TextFile.cxx @@ -19,59 +19,63 @@ #include "config.h" #include "TextFile.hxx" +#include "util/Alloc.hxx" #include "fs/Path.hxx" #include "fs/FileSystem.hxx" -#include - #include #include +#include TextFile::TextFile(Path path_fs) :file(FOpen(path_fs, FOpenMode::ReadText)), - buffer(g_string_sized_new(step)) {} + buffer((char *)xalloc(step)), capacity(step), length(0) {} TextFile::~TextFile() { + free(buffer); + if (file != nullptr) fclose(file); - - g_string_free(buffer, true); } char * TextFile::ReadLine() { - gsize length = 0, i; - char *p; - assert(file != nullptr); - assert(buffer != nullptr); - assert(buffer->allocated_len >= step); - while (buffer->len < max_length) { - p = fgets(buffer->str + length, - buffer->allocated_len - length, file); + while (true) { + if (length >= capacity) { + if (capacity >= max_length) + /* too large already - bail out */ + return nullptr; + + capacity <<= 1; + char *new_buffer = (char *)realloc(buffer, capacity); + if (new_buffer == nullptr) + /* out of memory - bail out */ + return nullptr; + } + + char *p = fgets(buffer + length, capacity - length, file); if (p == nullptr) { if (length == 0 || ferror(file)) return nullptr; break; } - i = strlen(buffer->str + length); - length += i; - if (i < step - 1 || buffer->str[length - 1] == '\n') + length += strlen(buffer + length); + if (buffer[length - 1] == '\n') break; - - g_string_set_size(buffer, length + step); } /* remove the newline characters */ - if (buffer->str[length - 1] == '\n') + if (buffer[length - 1] == '\n') --length; - if (buffer->str[length - 1] == '\r') + if (buffer[length - 1] == '\r') --length; - g_string_set_size(buffer, length); - return buffer->str; + buffer[length] = 0; + length = 0; + return buffer; } diff --git a/src/fs/TextFile.hxx b/src/fs/TextFile.hxx index b4b850c0f..e3a712a88 100644 --- a/src/fs/TextFile.hxx +++ b/src/fs/TextFile.hxx @@ -23,9 +23,9 @@ #include "Compiler.h" #include +#include class Path; -typedef struct _GString GString; class TextFile { static constexpr size_t max_length = 512 * 1024; @@ -33,7 +33,8 @@ class TextFile { FILE *const file; - GString *const buffer; + char *buffer; + size_t capacity, length; public: TextFile(Path path_fs); -- cgit v1.2.3