From b2d7a0b4b6b5b86a8c50fa7e9cf0e4659098a2da Mon Sep 17 00:00:00 2001 From: Misa Date: Wed, 22 Sep 2021 19:51:36 -0700 Subject: [PATCH] Rewrite STDIN loading to not use STL Previously, loading STDIN used std::istreambuf_iterator and std::vector and whatnot because... I guess it was less typing? But this isn't 1989; we have the disk space to spare and we don't need to use fancy stuff just to save on typing. It's not that hard to implement an array that regrows to the nearest power of two every time. --- desktop_version/src/FileSystemUtils.cpp | 87 +++++++++++++++++++------ 1 file changed, 67 insertions(+), 20 deletions(-) diff --git a/desktop_version/src/FileSystemUtils.cpp b/desktop_version/src/FileSystemUtils.cpp index 6caabdcb..49fb220c 100644 --- a/desktop_version/src/FileSystemUtils.cpp +++ b/desktop_version/src/FileSystemUtils.cpp @@ -1,12 +1,8 @@ -#include -#include #include #include #include #include -#include #include -#include #include "BinaryBlob.h" #include "Exit.h" @@ -189,12 +185,20 @@ end: return retval; } +static unsigned char* stdin_buffer = NULL; +static size_t stdin_length = 0; + void FILESYSTEM_deinit(void) { if (PHYSFS_isInit()) { PHYSFS_deinit(); } + if (stdin_buffer != NULL) + { + SDL_free(stdin_buffer); + stdin_buffer = NULL; + } } char *FILESYSTEM_getUserSaveDirectory(void) @@ -654,6 +658,56 @@ bool FILESYSTEM_isAssetMounted(const char* filename) void FILESYSTEM_freeMemory(unsigned char **mem); +static void load_stdin(void) +{ + size_t pos = 0; + /* A .vvvvvv file with nothing is at least 140K... + * initial size of 1K shouldn't hurt. */ +#define INITIAL_SIZE 1024 + size_t alloc_size = INITIAL_SIZE; + stdin_buffer = (unsigned char*) SDL_malloc(INITIAL_SIZE); +#undef INITIAL_SIZE + + if (stdin_buffer == NULL) + { + VVV_exit(1); + } + + while (true) + { + int ch = fgetc(stdin); + bool end = ch == EOF; + if (end) + { + /* Add null terminator. There's no observable change in + * behavior if addnull is always true, but not vice versa. */ + ch = '\0'; + } + + if (pos == alloc_size) + { + unsigned char *tmp; + alloc_size *= 2; + tmp = (unsigned char*) SDL_realloc((void*) stdin_buffer, alloc_size); + if (tmp == NULL) + { + VVV_exit(1); + } + stdin_buffer = tmp; + } + + stdin_buffer[pos] = ch; + ++pos; + + if (end) + { + break; + } + } + + stdin_length = pos - 1; +} + void FILESYSTEM_loadFileToMemory( const char *name, unsigned char **mem, @@ -672,30 +726,23 @@ void FILESYSTEM_loadFileToMemory( if (SDL_strcmp(name, "levels/special/stdin.vvvvvv") == 0) { // this isn't *technically* necessary when piping directly from a file, but checking for that is annoying - static std::vector STDIN_BUFFER; - static bool STDIN_LOADED = false; - size_t stdin_length; - if (!STDIN_LOADED) + if (stdin_buffer == NULL) { - std::istreambuf_iterator begin(std::cin), end; - STDIN_BUFFER.assign(begin, end); - STDIN_BUFFER.push_back(0); // there's no observable change in behavior if addnull is always true, but not vice versa - STDIN_LOADED = true; + load_stdin(); + } + + *mem = (unsigned char*) SDL_malloc(stdin_length + 1); /* + 1 for null */ + if (*mem == NULL) + { + VVV_exit(1); } - stdin_length = STDIN_BUFFER.size() - 1; if (len != NULL) { *len = stdin_length; } - ++stdin_length; - *mem = static_cast(SDL_malloc(stdin_length)); // STDIN_BUFFER.data() causes double-free - if (*mem == NULL) - { - VVV_exit(1); - } - std::copy(STDIN_BUFFER.begin(), STDIN_BUFFER.end(), reinterpret_cast(*mem)); + SDL_memcpy((void*) *mem, (void*) stdin_buffer, stdin_length + 1); return; }