// This file is a part of Framsticks SDK. http://www.framsticks.com/ // Copyright (C) 1999-2024 Maciej Komosinski and Szymon Ulatowski. // See LICENSE.txt for details. #include "util-file.h" #include "nonstd_stdio.h" #include "nonstd.h" #include "log.h" #ifdef USE_VIRTFILE #include #endif #ifdef DEBUGGING_READWRITECOMPLETEFILE #include #endif bool readCompleteFile(const char* filename, vector& data, bool warn_on_missing_file) { bool ok = false; #ifdef USE_VIRTFILE #ifdef DEBUGGING_READWRITECOMPLETEFILE logPrintf("", "readCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename); #endif // if (!isAbsolutePath(filename)) { VirtFILE *f = Vfopen(filename, FOPEN_READ_BINARY); if (f) { int size = f->getSize(); data.resize(size); int przeczytane = (int)f->Vread(&data[0], size, 1); ok = (przeczytane == 1); delete f; } } // else #endif { #ifdef DEBUGGING_READWRITECOMPLETEFILE if (isAbsolutePath(filename)) logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename); else logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str()); #endif MFILE *f = mfopen(filename, FOPEN_READ_BINARY); #ifdef DEBUGGING_READWRITECOMPLETEFILE logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen status: %s", f ? "ok" : "fail"); #endif if (f) { int size = getFileSize(f); data.resize(size); int przeczytane = (int)mfread(&data[0], size, 1, f); mfclose(f); ok = (przeczytane == 1); } } if (warn_on_missing_file && !ok) logPrintf("", "readCompleteFile", LOG_WARN, "Couldn't open file '%s'", filename); #ifdef DEBUGGING_READWRITECOMPLETEFILE logPrintf("", "readCompleteFile", LOG_DEBUG, "bytes:%d status: %s", data.size(), ok ? "ok" : "fail"); #endif return ok; } bool readCompleteFile(const char* filename, string& out, bool warn_on_missing_file) { vector data; if (readCompleteFile(filename, data, warn_on_missing_file)) { out = string(&data[0], data.size()); return true; } return false; } bool writeCompleteFile(const char* filename, const span& data, bool warn_on_fail) { #ifdef USE_VIRTFILE #ifdef DEBUGGING_READWRITECOMPLETEFILE logPrintf("", "writeCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename); #endif VirtFILE *f = Vfopen(filename, FOPEN_WRITE_BINARY); bool ok = f != NULL; if (f) { int zapisane = data.size() > 0 ? (int)f->Vwrite(data.begin(), data.size(), 1) : 1; //size()==0 is a special case (creating an empty file) delete f; ok &= (zapisane == 1); } #else #ifdef DEBUGGING_READWRITECOMPLETEFILE if (isAbsolutePath(filename)) logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename); else logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str()); #endif MFILE *f = mfopen(filename, FOPEN_WRITE_BINARY); bool ok = f != NULL; #ifdef DEBUGGING_READWRITECOMPLETEFILE logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen status: %s", ok ? "ok" : "fail"); #endif if (f) { int zapisane = data.size() > 0 ? (int)mfwrite(data.begin(), data.size(), 1, f) : 1; //size()==0 is a special case (creating an empty file) mfclose(f); ok &= (zapisane == 1); } #endif if (warn_on_fail && !ok) logPrintf("", "writeCompleteFile", LOG_WARN, "Couldn't write file '%s'", filename); #ifdef DEBUGGING_READWRITECOMPLETEFILE logPrintf("", "writeCompleteFile", LOG_DEBUG, "status: %s", ok ? "ok" : "fail"); #endif return ok; } bool writeCompleteFile(const char* filename, const span& data, bool warn_on_fail) { return writeCompleteFile(filename, span((char*)&data[0], data.size()), warn_on_fail); } bool writeCompleteFile(const char* filename, const vector& data, bool warn_on_fail) { return writeCompleteFile(filename, span((char*)&data[0], data.size()), warn_on_fail); } bool writeCompleteFile(const char* filename, const string& text, bool warn_on_fail) { return writeCompleteFile(filename, span((char*)text.c_str(), text.size()), warn_on_fail); } // Just like fgets(), but string length is unlimited and does not store trailing \r \n #ifdef USE_VIRTFILE string readUntilEOL(VirtFILE *f) #else string readUntilEOL(FILE *f) #endif { char buf[100]; char* line; std::string ret; bool endofline; while ((line = #ifdef USE_VIRTFILE f->Vgets(buf, sizeof(buf)) #else fgets(buf, sizeof(buf), f) #endif )) { char* end = line + strlen(line); endofline = false; while (end > line) if ((end[-1] == '\n') || (end[-1] == '\r')) { endofline = true; end--; } else break; ret += std::string(line, end - line); if (endofline) break; } return ret; }