Commit 1709ab68 authored by Max Kellermann's avatar Max Kellermann

fs/TextFile: use custom allocation instead of GString

parent ce925ba5
...@@ -1322,9 +1322,9 @@ endif ...@@ -1322,9 +1322,9 @@ endif
test_read_conf_LDADD = \ test_read_conf_LDADD = \
libconf.a \ libconf.a \
libutil.a \
libsystem.a \ libsystem.a \
libfs.a \ libfs.a \
libutil.a \
$(GLIB_LIBS) $(GLIB_LIBS)
test_read_conf_SOURCES = \ test_read_conf_SOURCES = \
src/Log.cxx src/LogBackend.cxx \ src/Log.cxx src/LogBackend.cxx \
...@@ -1543,9 +1543,9 @@ endif ...@@ -1543,9 +1543,9 @@ endif
test_run_filter_LDADD = \ test_run_filter_LDADD = \
$(FILTER_LIBS) \ $(FILTER_LIBS) \
libconf.a \ libconf.a \
libutil.a \
libsystem.a \ libsystem.a \
libfs.a \ libfs.a \
libutil.a \
$(GLIB_LIBS) $(GLIB_LIBS)
test_run_filter_SOURCES = test/run_filter.cxx \ test_run_filter_SOURCES = test/run_filter.cxx \
test/FakeReplayGainConfig.cxx \ test/FakeReplayGainConfig.cxx \
...@@ -1681,10 +1681,10 @@ test_read_mixer_LDADD = \ ...@@ -1681,10 +1681,10 @@ test_read_mixer_LDADD = \
libmixer_plugins.a \ libmixer_plugins.a \
$(OUTPUT_LIBS) \ $(OUTPUT_LIBS) \
libconf.a \ libconf.a \
libutil.a \
libevent.a \ libevent.a \
libsystem.a \ libsystem.a \
libfs.a \ libfs.a \
libutil.a \
$(GLIB_LIBS) $(GLIB_LIBS)
test_read_mixer_SOURCES = test/read_mixer.cxx \ test_read_mixer_SOURCES = test/read_mixer.cxx \
src/Log.cxx src/LogBackend.cxx \ src/Log.cxx src/LogBackend.cxx \
......
...@@ -19,59 +19,63 @@ ...@@ -19,59 +19,63 @@
#include "config.h" #include "config.h"
#include "TextFile.hxx" #include "TextFile.hxx"
#include "util/Alloc.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "fs/FileSystem.hxx" #include "fs/FileSystem.hxx"
#include <glib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
TextFile::TextFile(Path path_fs) TextFile::TextFile(Path path_fs)
:file(FOpen(path_fs, FOpenMode::ReadText)), :file(FOpen(path_fs, FOpenMode::ReadText)),
buffer(g_string_sized_new(step)) {} buffer((char *)xalloc(step)), capacity(step), length(0) {}
TextFile::~TextFile() TextFile::~TextFile()
{ {
free(buffer);
if (file != nullptr) if (file != nullptr)
fclose(file); fclose(file);
g_string_free(buffer, true);
} }
char * char *
TextFile::ReadLine() TextFile::ReadLine()
{ {
gsize length = 0, i;
char *p;
assert(file != nullptr); assert(file != nullptr);
assert(buffer != nullptr);
assert(buffer->allocated_len >= step);
while (buffer->len < max_length) { while (true) {
p = fgets(buffer->str + length, if (length >= capacity) {
buffer->allocated_len - length, file); 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 (p == nullptr) {
if (length == 0 || ferror(file)) if (length == 0 || ferror(file))
return nullptr; return nullptr;
break; break;
} }
i = strlen(buffer->str + length); length += strlen(buffer + length);
length += i; if (buffer[length - 1] == '\n')
if (i < step - 1 || buffer->str[length - 1] == '\n')
break; break;
g_string_set_size(buffer, length + step);
} }
/* remove the newline characters */ /* remove the newline characters */
if (buffer->str[length - 1] == '\n') if (buffer[length - 1] == '\n')
--length; --length;
if (buffer->str[length - 1] == '\r') if (buffer[length - 1] == '\r')
--length; --length;
g_string_set_size(buffer, length); buffer[length] = 0;
return buffer->str; length = 0;
return buffer;
} }
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
#include "Compiler.h" #include "Compiler.h"
#include <stdio.h> #include <stdio.h>
#include <stddef.h>
class Path; class Path;
typedef struct _GString GString;
class TextFile { class TextFile {
static constexpr size_t max_length = 512 * 1024; static constexpr size_t max_length = 512 * 1024;
...@@ -33,7 +33,8 @@ class TextFile { ...@@ -33,7 +33,8 @@ class TextFile {
FILE *const file; FILE *const file;
GString *const buffer; char *buffer;
size_t capacity, length;
public: public:
TextFile(Path path_fs); TextFile(Path path_fs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment