1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef TITANIC_SIMPLE_FILE_H
24 #define TITANIC_SIMPLE_FILE_H
25 
26 #include "common/file.h"
27 #include "titanic/support/rect.h"
28 #include "common/savefile.h"
29 #include "common/stream.h"
30 #include "common/zlib.h"
31 #include "titanic/support/string.h"
32 
33 namespace Titanic {
34 
35 class Decompressor;
36 class DecompressorData;
37 
38 /**
39  * Simple ScummVM File descendent that throws a wobbly if
40  * the file it tries to open isn't present
41  */
42 class File : public Common::File {
43 public:
44 	bool open(const Common::Path &filename) override;
45 };
46 
47 /**
48  * This class implements basic reading and writing to files
49  */
50 class SimpleFile {
51 private:
52 	/**
53 	 * Skip over any pending spaces
54 	 */
55 	void skipSpaces();
56 protected:
57 	Common::SeekableReadStream *_inStream;
58 	Common::OutSaveFile *_outStream;
59 	int _lineCount;
60 public:
61 	SimpleFile();
62 	virtual ~SimpleFile();
63 
64 	operator Common::SeekableReadStream &() { return *_inStream; }
65 	operator Common::WriteStream &() { return *_outStream; }
66 
67 	/**
68 	 * Set up a stream for read access
69 	 */
70 	virtual void open(Common::SeekableReadStream *stream);
71 
72 	/**
73 	 * Set up a stream for write access
74 	 */
75 	virtual void open(Common::OutSaveFile *stream);
76 
77 	/**
78 	 * Close the file
79 	 */
80 	virtual void close();
81 
82 	/**
83 	 * Read from the file with validation
84 	 */
85 	virtual void safeRead(void *dst, size_t count);
86 
87 	/**
88 	 * Read from the file
89 	 */
90 	virtual size_t unsafeRead(void *dst, size_t count);
91 
92 	/**
93 	 * Write out data
94 	 */
95 	virtual size_t write(const void *src, size_t count) const;
96 
97 	/**
98 	 * Seek
99 	 */
100 	virtual void seek(int offset, int origin);
101 	/**
102 	 * Read a byte
103 	 */
104 	byte readByte();
105 
106 	/**
107 	 * Read a 16-bit LE number
108 	 */
109 	uint readUint16LE();
110 
111 	/**
112 	 * Read a 32-bit LE number
113 	 */
114 	uint readUint32LE();
115 
116 	/**
117 	 * Read a string from the file
118 	 */
119 	CString readString();
120 
121 	/**
122 	 * Read a number from the file
123 	 */
124 	int readNumber();
125 
126 	/**
127 	 * Read a floating point number from the file
128 	 */
129 	double readFloat();
130 
131 	/**
132 	 * Read in a point
133 	 */
134 	Point readPoint();
135 
136 	/**
137 	 * Read in a rect
138 	 */
139 	Rect readRect();
140 
141 	/**
142 	 * Rect in a bounds
143 	 */
144 	Rect readBounds();
145 
146 	/**
147 	 * Read a string and copy it into an optionally passed buffer
148 	 */
149 	void readBuffer(char *buffer = nullptr, size_t count = 0);
150 
151 	/**
152 	 * Scan in values from the file
153 	 */
154 	bool scanf(const char *format, ...);
155 
156 	/**
157 	 * Write out a byte
158 	 */
writeByte(byte b)159 	void writeByte(byte b) { write(&b, 1); }
160 
161 	/**
162 	 * Write out a raw 16-bit LE number
163 	 */
164 	void writeUint16LE(uint val);
165 
166 	/**
167 	 * Write out a raw 32-bit LE number
168 	 */
169 	void writeUint32LE(uint val);
170 
171 	/**
172 	 * Write a string line
173 	 */
174 	void writeLine(const CString &str) const;
175 
176 	/**
177 	 * Write a string
178 	 */
179 	void writeString(const CString &str) const;
180 
181 	/**
182 	 * Write a quoted string
183 	 */
184 	void writeQuotedString(const CString &str) const;
185 
186 	/**
187 	 * Write a quoted string line
188 	 */
189 	void writeQuotedLine(const CString &str, int indent) const;
190 
191 	/**
192 	 * Write a number to file
193 	 */
194 	void writeNumber(int val) const;
195 
196 	/**
197 	 * Write a number line to file
198 	 */
199 	void writeNumberLine(int val, int indent) const;
200 
201 	/**
202 	 * Write a floating point number
203 	 */
204 	void writeFloat(double val) const;
205 
206 	/**
207 	 * Write a floating point number as a line
208 	 */
209 	void writeFloatLine(double val, int indent) const;
210 
211 	/**
212 	 * Write out a point line
213 	 */
214 	void writePoint(const Point &pt, int indent)const;
215 
216 	/**
217 	 * Write out a rect line
218 	 */
219 	void writeRect(const Rect &r, int indent) const;
220 
221 	/**
222 	 * Write out a bounds line
223 	 */
224 	void writeBounds(const Rect &r, int indent) const;
225 
226 	/**
227 	 * Write out a string using a format specifier, just like fprintf
228 	 */
229 	void writeFormat(const char *format, ...) const;
230 
231 	/**
232 	 * Write out a number of tabs to form an indent in the output
233 	 */
234 	void writeIndent(uint indent) const;
235 
236 	/**
237 	 * Validates that the following non-space character is either
238 	 * an opening or closing squiggly bracket denoting a class
239 	 * definition start or end. Returns true if it's a class start
240 	 */
241 	bool isClassStart();
242 
243 	/**
244 	 * Write the starting header for a class definition
245 	 */
246 	void writeClassStart(const CString &classStr, int indent);
247 
248 	/**
249 	 * Write out the ending footer for a class definition
250 	 */
251 	void writeClassEnd(int indent);
252 
253 	/**
254 	 * Return true if the stream has finished being read
255 	 */
eos()256 	bool eos() const {
257 		assert(_inStream);
258 		return _inStream->pos() >= _inStream->size();
259 	}
260 };
261 
262 /**
263  * Derived file that handles compressed files
264  */
265 class CompressedFile : public SimpleFile {
266 public:
CompressedFile()267 	CompressedFile() : SimpleFile() {}
~CompressedFile()268 	~CompressedFile() override {}
269 
270 	/**
271 	 * Set up a stream for read access
272 	 */
open(Common::SeekableReadStream * stream)273 	void open(Common::SeekableReadStream *stream) override {
274 		SimpleFile::open(Common::wrapCompressedReadStream(stream));
275 	}
276 
277 	/**
278 	 * Set up a stream for write access
279 	 */
open(Common::OutSaveFile * stream)280 	void open(Common::OutSaveFile *stream) override {
281 		SimpleFile::open(new Common::OutSaveFile(Common::wrapCompressedWriteStream(stream)));
282 	}
283 };
284 
285 /**
286  * Derived file that handles WAD archives containing multiple files
287  */
288 class StdCWadFile : public SimpleFile {
289 public:
StdCWadFile()290 	StdCWadFile() : SimpleFile() {}
~StdCWadFile()291 	~StdCWadFile() override {}
292 
293 	/**
294 	 * Open up the specified file
295 	 */
296 	virtual bool open(const Common::String &filename);
297 
298 	/**
299 	 * Unsupported open method from parent class
300 	 */
open(Common::SeekableReadStream * stream)301 	void open(Common::SeekableReadStream *stream) override {}
302 
303 	/**
304 	 * Unsupported open method from parent class
305 	 */
open(Common::OutSaveFile * stream)306 	void open(Common::OutSaveFile *stream) override {}
307 
308 	/**
309 	 * Return a reference to the read stream
310 	 */
readStream()311 	Common::SeekableReadStream *readStream() const { return _inStream; }
312 };
313 
314 /**
315  * General purpose support method for reading an ASCIIZ string from a stream
316  */
317 CString readStringFromStream(Common::SeekableReadStream *s);
318 
319 } // End of namespace Titanic
320 
321 #endif /* TITANIC_SIMPLE_FILE_H */
322