[840] | 1 | // This file is a part of Framsticks SDK. http://www.framsticks.com/
|
---|
[1331] | 2 | // Copyright (C) 1999-2024 Maciej Komosinski and Szymon Ulatowski.
|
---|
[840] | 3 | // See LICENSE.txt for details.
|
---|
| 4 |
|
---|
| 5 | #include "util-file.h"
|
---|
| 6 | #include "nonstd_stdio.h"
|
---|
| 7 | #include "nonstd.h"
|
---|
| 8 | #include "log.h"
|
---|
| 9 | #ifdef USE_VIRTFILE
|
---|
| 10 | #include <common/virtfile/virtfile.h>
|
---|
| 11 | #endif
|
---|
[1153] | 12 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
| 13 | #include <common/dirs.h>
|
---|
| 14 | #endif
|
---|
[840] | 15 |
|
---|
| 16 | bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file)
|
---|
| 17 | {
|
---|
| 18 | bool ok = false;
|
---|
| 19 | #ifdef USE_VIRTFILE
|
---|
[1153] | 20 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 21 | logPrintf("", "readCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename);
|
---|
[1153] | 22 | #endif
|
---|
[1331] | 23 | // if (!isAbsolutePath(filename))
|
---|
[840] | 24 | {
|
---|
[1331] | 25 | VirtFILE *f = Vfopen(filename, FOPEN_READ_BINARY);
|
---|
[840] | 26 | if (f)
|
---|
| 27 | {
|
---|
[1331] | 28 | int size = f->getSize();
|
---|
[840] | 29 | data.resize(size);
|
---|
[888] | 30 | int przeczytane = (int)f->Vread(&data[0], size, 1);
|
---|
| 31 | ok = (przeczytane == 1);
|
---|
[840] | 32 | delete f;
|
---|
| 33 | }
|
---|
| 34 | }
|
---|
[1331] | 35 | // else
|
---|
[840] | 36 | #endif
|
---|
| 37 | {
|
---|
[1153] | 38 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 39 | if (isAbsolutePath(filename))
|
---|
| 40 | logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename);
|
---|
| 41 | else
|
---|
| 42 | logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str());
|
---|
[1153] | 43 | #endif
|
---|
[840] | 44 | MFILE *f = mfopen(filename, FOPEN_READ_BINARY);
|
---|
[1153] | 45 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 46 | logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen status: %s", f ? "ok" : "fail");
|
---|
[1153] | 47 | #endif
|
---|
[840] | 48 | if (f)
|
---|
| 49 | {
|
---|
| 50 | int size = getFileSize(f);
|
---|
| 51 | data.resize(size);
|
---|
[888] | 52 | int przeczytane = (int)mfread(&data[0], size, 1, f);
|
---|
[840] | 53 | mfclose(f);
|
---|
[888] | 54 | ok = (przeczytane == 1);
|
---|
[840] | 55 | }
|
---|
| 56 | }
|
---|
| 57 | if (warn_on_missing_file && !ok)
|
---|
[1153] | 58 | logPrintf("", "readCompleteFile", LOG_WARN, "Couldn't open file '%s'", filename);
|
---|
| 59 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 60 | logPrintf("", "readCompleteFile", LOG_DEBUG, "bytes:%d status: %s", data.size(), ok ? "ok" : "fail");
|
---|
[1153] | 61 | #endif
|
---|
[840] | 62 | return ok;
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | bool readCompleteFile(const char* filename, string& out, bool warn_on_missing_file)
|
---|
| 66 | {
|
---|
| 67 | vector<char> data;
|
---|
| 68 | if (readCompleteFile(filename, data, warn_on_missing_file))
|
---|
| 69 | {
|
---|
| 70 | out = string(&data[0], data.size());
|
---|
| 71 | return true;
|
---|
| 72 | }
|
---|
| 73 | return false;
|
---|
| 74 | }
|
---|
| 75 |
|
---|
[1331] | 76 | bool writeCompleteFile(const char* filename, const span<char>& data, bool warn_on_fail)
|
---|
[840] | 77 | {
|
---|
| 78 | #ifdef USE_VIRTFILE
|
---|
[1153] | 79 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 80 | logPrintf("", "writeCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename);
|
---|
[1153] | 81 | #endif
|
---|
[840] | 82 | VirtFILE *f = Vfopen(filename, FOPEN_WRITE_BINARY);
|
---|
| 83 | bool ok = f != NULL;
|
---|
| 84 | if (f)
|
---|
| 85 | {
|
---|
[1331] | 86 | int zapisane = data.size() > 0 ? (int)f->Vwrite(data.begin(), data.size(), 1) : 1; //size()==0 is a special case (creating an empty file)
|
---|
[840] | 87 | delete f;
|
---|
[888] | 88 | ok &= (zapisane == 1);
|
---|
[840] | 89 | }
|
---|
| 90 | #else
|
---|
[1153] | 91 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
| 92 | if (isAbsolutePath(filename))
|
---|
[1331] | 93 | logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename);
|
---|
[1153] | 94 | else
|
---|
[1331] | 95 | logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str());
|
---|
[1153] | 96 | #endif
|
---|
[840] | 97 | MFILE *f = mfopen(filename, FOPEN_WRITE_BINARY);
|
---|
| 98 | bool ok = f != NULL;
|
---|
[1153] | 99 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 100 | logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen status: %s", ok ? "ok" : "fail");
|
---|
[1153] | 101 | #endif
|
---|
[840] | 102 | if (f)
|
---|
| 103 | {
|
---|
[1331] | 104 | int zapisane = data.size() > 0 ? (int)mfwrite(data.begin(), data.size(), 1, f) : 1; //size()==0 is a special case (creating an empty file)
|
---|
[840] | 105 | mfclose(f);
|
---|
[888] | 106 | ok &= (zapisane == 1);
|
---|
[840] | 107 | }
|
---|
| 108 | #endif
|
---|
| 109 | if (warn_on_fail && !ok)
|
---|
[1153] | 110 | logPrintf("", "writeCompleteFile", LOG_WARN, "Couldn't write file '%s'", filename);
|
---|
| 111 | #ifdef DEBUGGING_READWRITECOMPLETEFILE
|
---|
[1331] | 112 | logPrintf("", "writeCompleteFile", LOG_DEBUG, "status: %s", ok ? "ok" : "fail");
|
---|
[1153] | 113 | #endif
|
---|
[840] | 114 | return ok;
|
---|
| 115 | }
|
---|
| 116 |
|
---|
[1331] | 117 | bool writeCompleteFile(const char* filename, const span<uint8_t>& data, bool warn_on_fail)
|
---|
[840] | 118 | {
|
---|
[1331] | 119 | return writeCompleteFile(filename, span<char>((char*)&data[0], data.size()), warn_on_fail);
|
---|
[840] | 120 | }
|
---|
[1124] | 121 |
|
---|
[1331] | 122 | bool writeCompleteFile(const char* filename, const vector<char>& data, bool warn_on_fail)
|
---|
| 123 | {
|
---|
| 124 | return writeCompleteFile(filename, span<char>((char*)&data[0], data.size()), warn_on_fail);
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | bool writeCompleteFile(const char* filename, const string& text, bool warn_on_fail)
|
---|
| 128 | {
|
---|
| 129 | return writeCompleteFile(filename, span<char>((char*)text.c_str(), text.size()), warn_on_fail);
|
---|
| 130 | }
|
---|
| 131 |
|
---|
| 132 |
|
---|
[1124] | 133 | // Just like fgets(), but string length is unlimited and does not store trailing \r \n
|
---|
[1153] | 134 | #ifdef USE_VIRTFILE
|
---|
[1124] | 135 | string readUntilEOL(VirtFILE *f)
|
---|
[1153] | 136 | #else
|
---|
| 137 | string readUntilEOL(FILE *f)
|
---|
| 138 | #endif
|
---|
[1124] | 139 | {
|
---|
| 140 | char buf[100];
|
---|
| 141 | char* line;
|
---|
| 142 | std::string ret;
|
---|
| 143 | bool endofline;
|
---|
[1153] | 144 | while ((line =
|
---|
| 145 | #ifdef USE_VIRTFILE
|
---|
[1331] | 146 | f->Vgets(buf, sizeof(buf))
|
---|
[1153] | 147 | #else
|
---|
[1331] | 148 | fgets(buf, sizeof(buf), f)
|
---|
[1153] | 149 | #endif
|
---|
[1331] | 150 | ))
|
---|
[1124] | 151 | {
|
---|
| 152 | char* end = line + strlen(line);
|
---|
| 153 | endofline = false;
|
---|
| 154 | while (end > line)
|
---|
| 155 | if ((end[-1] == '\n') || (end[-1] == '\r'))
|
---|
| 156 | {
|
---|
| 157 | endofline = true;
|
---|
| 158 | end--;
|
---|
| 159 | }
|
---|
| 160 | else
|
---|
| 161 | break;
|
---|
| 162 | ret += std::string(line, end - line);
|
---|
| 163 | if (endofline) break;
|
---|
| 164 | }
|
---|
| 165 | return ret;
|
---|
| 166 | }
|
---|