source: cpp/common/util-file.cpp @ 1331

Last change on this file since 1331 was 1331, checked in by Maciej Komosinski, 4 days ago
  • more input types in writeCompleteFile(), with "span" being the common interface
  • writeCompleteFile() no longer produces a false warning when writing an empty file
File size: 4.8 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2024  Maciej Komosinski and Szymon Ulatowski.
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
12#ifdef DEBUGGING_READWRITECOMPLETEFILE
13#include <common/dirs.h>
14#endif
15
16bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file)
17{
18        bool ok = false;
19#ifdef USE_VIRTFILE
20#ifdef DEBUGGING_READWRITECOMPLETEFILE
21        logPrintf("", "readCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename);
22#endif 
23        //      if (!isAbsolutePath(filename))
24        {
25                VirtFILE *f = Vfopen(filename, FOPEN_READ_BINARY);
26                if (f)
27                {
28                        int size = f->getSize();
29                        data.resize(size);
30                        int przeczytane = (int)f->Vread(&data[0], size, 1);
31                        ok = (przeczytane == 1);
32                        delete f;
33                }
34        }
35        //      else
36#endif
37        {
38#ifdef DEBUGGING_READWRITECOMPLETEFILE
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());
43#endif 
44                MFILE *f = mfopen(filename, FOPEN_READ_BINARY);
45#ifdef DEBUGGING_READWRITECOMPLETEFILE
46                logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen status: %s", f ? "ok" : "fail");
47#endif
48                if (f)
49                {
50                        int size = getFileSize(f);
51                        data.resize(size);
52                        int przeczytane = (int)mfread(&data[0], size, 1, f);
53                        mfclose(f);
54                        ok = (przeczytane == 1);
55                }
56        }
57        if (warn_on_missing_file && !ok)
58                logPrintf("", "readCompleteFile", LOG_WARN, "Couldn't open file '%s'", filename);
59#ifdef DEBUGGING_READWRITECOMPLETEFILE
60        logPrintf("", "readCompleteFile", LOG_DEBUG, "bytes:%d status: %s", data.size(), ok ? "ok" : "fail");
61#endif
62        return ok;
63}
64
65bool 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
76bool writeCompleteFile(const char* filename, const span<char>& data, bool warn_on_fail)
77{
78#ifdef USE_VIRTFILE
79#ifdef DEBUGGING_READWRITECOMPLETEFILE
80        logPrintf("", "writeCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename);
81#endif 
82        VirtFILE *f = Vfopen(filename, FOPEN_WRITE_BINARY);
83        bool ok = f != NULL;
84        if (f)
85        {
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)
87                delete f;
88                ok &= (zapisane == 1);
89        }
90#else
91#ifdef DEBUGGING_READWRITECOMPLETEFILE
92        if (isAbsolutePath(filename))
93                logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename);
94        else
95                logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str());
96#endif
97        MFILE *f = mfopen(filename, FOPEN_WRITE_BINARY);
98        bool ok = f != NULL;
99#ifdef DEBUGGING_READWRITECOMPLETEFILE
100        logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen status: %s", ok ? "ok" : "fail");
101#endif
102        if (f)
103        {
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)
105                mfclose(f);
106                ok &= (zapisane == 1);
107        }
108#endif
109        if (warn_on_fail && !ok)
110                logPrintf("", "writeCompleteFile", LOG_WARN, "Couldn't write file '%s'", filename);
111#ifdef DEBUGGING_READWRITECOMPLETEFILE
112        logPrintf("", "writeCompleteFile", LOG_DEBUG, "status: %s", ok ? "ok" : "fail");
113#endif
114        return ok;
115}
116
117bool writeCompleteFile(const char* filename, const span<uint8_t>& data, bool warn_on_fail)
118{
119        return writeCompleteFile(filename, span<char>((char*)&data[0], data.size()), warn_on_fail);
120}
121
122bool 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
127bool 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
133// Just like fgets(), but string length is unlimited and does not store trailing \r \n
134#ifdef USE_VIRTFILE
135string readUntilEOL(VirtFILE *f)
136#else
137string readUntilEOL(FILE *f)
138#endif
139{
140        char buf[100];
141        char* line;
142        std::string ret;
143        bool endofline;
144        while ((line =
145#ifdef USE_VIRTFILE
146                f->Vgets(buf, sizeof(buf))
147#else
148                fgets(buf, sizeof(buf), f)
149#endif
150                ))
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}
Note: See TracBrowser for help on using the repository browser.