1 #ifndef FILES_H
2 #define FILES_H
3 
4 #include <stdio.h>
5 #include <zlib.h>
6 #include "bzlib.h"
7 #include "doomtype.h"
8 #include "m_swap.h"
9 
10 class FileReaderBase
11 {
12 public:
~FileReaderBase()13 	virtual ~FileReaderBase() {}
14 	virtual long Read (void *buffer, long len) = 0;
15 
16 	FileReaderBase &operator>> (BYTE &v)
17 	{
18 		Read (&v, 1);
19 		return *this;
20 	}
21 
22 	FileReaderBase &operator>> (SBYTE &v)
23 	{
24 		Read (&v, 1);
25 		return *this;
26 	}
27 
28 	FileReaderBase &operator>> (WORD &v)
29 	{
30 		Read (&v, 2);
31 		v = LittleShort(v);
32 		return *this;
33 	}
34 
35 	FileReaderBase &operator>> (SWORD &v)
36 	{
37 		Read (&v, 2);
38 		v = LittleShort(v);
39 		return *this;
40 	}
41 
42 	FileReaderBase &operator>> (DWORD &v)
43 	{
44 		Read (&v, 4);
45 		v = LittleLong(v);
46 		return *this;
47 	}
48 
49 	FileReaderBase &operator>> (fixed_t &v)
50 	{
51 		Read (&v, 4);
52 		v = LittleLong(v);
53 		return *this;
54 	}
55 
56 };
57 
58 
59 class FileReader : public FileReaderBase
60 {
61 public:
62 	FileReader ();
63 	FileReader (const char *filename);
64 	FileReader (FILE *file);
65 	FileReader (FILE *file, long length);
66 	bool Open (const char *filename);
67 	virtual ~FileReader ();
68 
69 	virtual long Tell () const;
70 	virtual long Seek (long offset, int origin);
71 	virtual long Read (void *buffer, long len);
72 	virtual char *Gets(char *strbuf, int len);
GetLength()73 	long GetLength () const { return Length; }
74 
75 	// If you use the underlying FILE without going through this class,
76 	// you must call ResetFilePtr() before using this class again.
77 	void ResetFilePtr ();
78 
GetFile()79 	FILE *GetFile () const { return File; }
GetBuffer()80 	virtual const char *GetBuffer() const { return NULL; }
81 
82 	FileReader &operator>> (BYTE &v)
83 	{
84 		Read (&v, 1);
85 		return *this;
86 	}
87 
88 	FileReader &operator>> (SBYTE &v)
89 	{
90 		Read (&v, 1);
91 		return *this;
92 	}
93 
94 	FileReader &operator>> (WORD &v)
95 	{
96 		Read (&v, 2);
97 		v = LittleShort(v);
98 		return *this;
99 	}
100 
101 	FileReader &operator>> (SWORD &v)
102 	{
103 		Read (&v, 2);
104 		v = LittleShort(v);
105 		return *this;
106 	}
107 
108 	FileReader &operator>> (DWORD &v)
109 	{
110 		Read (&v, 4);
111 		v = LittleLong(v);
112 		return *this;
113 	}
114 
115 
116 protected:
117 	FileReader (const FileReader &other, long length);
118 
119 	char *GetsFromBuffer(const char * bufptr, char *strbuf, int len);
120 
121 	FILE *File;
122 	long Length;
123 	long StartPos;
124 	long FilePos;
125 
126 private:
127 	long CalcFileLen () const;
128 protected:
129 	bool CloseOnDestruct;
130 };
131 
132 // Wraps around a FileReader to decompress a zlib stream
133 class FileReaderZ : public FileReaderBase
134 {
135 public:
136 	FileReaderZ (FileReader &file, bool zip=false);
137 	~FileReaderZ ();
138 
139 	virtual long Read (void *buffer, long len);
140 
141 	FileReaderZ &operator>> (BYTE &v)
142 	{
143 		Read (&v, 1);
144 		return *this;
145 	}
146 
147 	FileReaderZ &operator>> (SBYTE &v)
148 	{
149 		Read (&v, 1);
150 		return *this;
151 	}
152 
153 	FileReaderZ &operator>> (WORD &v)
154 	{
155 		Read (&v, 2);
156 		v = LittleShort(v);
157 		return *this;
158 	}
159 
160 	FileReaderZ &operator>> (SWORD &v)
161 	{
162 		Read (&v, 2);
163 		v = LittleShort(v);
164 		return *this;
165 	}
166 
167 	FileReaderZ &operator>> (DWORD &v)
168 	{
169 		Read (&v, 4);
170 		v = LittleLong(v);
171 		return *this;
172 	}
173 
174 	FileReaderZ &operator>> (fixed_t &v)
175 	{
176 		Read (&v, 4);
177 		v = LittleLong(v);
178 		return *this;
179 	}
180 
181 private:
182 	enum { BUFF_SIZE = 4096 };
183 
184 	FileReader &File;
185 	bool SawEOF;
186 	z_stream Stream;
187 	BYTE InBuff[BUFF_SIZE];
188 
189 	void FillBuffer ();
190 
191 	FileReaderZ &operator= (const FileReaderZ &) { return *this; }
192 };
193 
194 // Wraps around a FileReader to decompress a bzip2 stream
195 class FileReaderBZ2 : public FileReaderBase
196 {
197 public:
198 	FileReaderBZ2 (FileReader &file);
199 	~FileReaderBZ2 ();
200 
201 	long Read (void *buffer, long len);
202 
203 	FileReaderBZ2 &operator>> (BYTE &v)
204 	{
205 		Read (&v, 1);
206 		return *this;
207 	}
208 
209 	FileReaderBZ2 &operator>> (SBYTE &v)
210 	{
211 		Read (&v, 1);
212 		return *this;
213 	}
214 
215 	FileReaderBZ2 &operator>> (WORD &v)
216 	{
217 		Read (&v, 2);
218 		v = LittleShort(v);
219 		return *this;
220 	}
221 
222 	FileReaderBZ2 &operator>> (SWORD &v)
223 	{
224 		Read (&v, 2);
225 		v = LittleShort(v);
226 		return *this;
227 	}
228 
229 	FileReaderBZ2 &operator>> (DWORD &v)
230 	{
231 		Read (&v, 4);
232 		v = LittleLong(v);
233 		return *this;
234 	}
235 
236 	FileReaderBZ2 &operator>> (fixed_t &v)
237 	{
238 		Read (&v, 4);
239 		v = LittleLong(v);
240 		return *this;
241 	}
242 
243 private:
244 	enum { BUFF_SIZE = 4096 };
245 
246 	FileReader &File;
247 	bool SawEOF;
248 	bz_stream Stream;
249 	BYTE InBuff[BUFF_SIZE];
250 
251 	void FillBuffer ();
252 
253 	FileReaderBZ2 &operator= (const FileReaderBZ2 &) { return *this; }
254 };
255 
256 // Wraps around a FileReader to decompress a lzma stream
257 class FileReaderLZMA : public FileReaderBase
258 {
259 	struct StreamPointer;
260 
261 public:
262 	FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip);
263 	~FileReaderLZMA ();
264 
265 	long Read (void *buffer, long len);
266 
267 	FileReaderLZMA &operator>> (BYTE &v)
268 	{
269 		Read (&v, 1);
270 		return *this;
271 	}
272 
273 	FileReaderLZMA &operator>> (SBYTE &v)
274 	{
275 		Read (&v, 1);
276 		return *this;
277 	}
278 
279 	FileReaderLZMA &operator>> (WORD &v)
280 	{
281 		Read (&v, 2);
282 		v = LittleShort(v);
283 		return *this;
284 	}
285 
286 	FileReaderLZMA &operator>> (SWORD &v)
287 	{
288 		Read (&v, 2);
289 		v = LittleShort(v);
290 		return *this;
291 	}
292 
293 	FileReaderLZMA &operator>> (DWORD &v)
294 	{
295 		Read (&v, 4);
296 		v = LittleLong(v);
297 		return *this;
298 	}
299 
300 	FileReaderLZMA &operator>> (fixed_t &v)
301 	{
302 		Read (&v, 4);
303 		v = LittleLong(v);
304 		return *this;
305 	}
306 
307 private:
308 	enum { BUFF_SIZE = 4096 };
309 
310 	FileReader &File;
311 	bool SawEOF;
312 	StreamPointer *Streamp;	// anonymous pointer to LKZA decoder struct - to avoid including the LZMA headers globally
313 	size_t Size;
314 	size_t InPos, InSize;
315 	size_t OutProcessed;
316 	BYTE InBuff[BUFF_SIZE];
317 
318 	void FillBuffer ();
319 
320 	FileReaderLZMA &operator= (const FileReaderLZMA &) { return *this; }
321 };
322 
323 class MemoryReader : public FileReader
324 {
325 public:
326 	MemoryReader (const char *buffer, long length);
327 	~MemoryReader ();
328 
329 	virtual long Tell () const;
330 	virtual long Seek (long offset, int origin);
331 	virtual long Read (void *buffer, long len);
332 	virtual char *Gets(char *strbuf, int len);
GetBuffer()333 	virtual const char *GetBuffer() const { return bufptr; }
334 
335 protected:
336 	const char * bufptr;
337 };
338 
339 class MemoryArrayReader : public FileReader
340 {
341 public:
342     MemoryArrayReader (const char *buffer, long length);
343     ~MemoryArrayReader ();
344 
345     virtual long Tell () const;
346     virtual long Seek (long offset, int origin);
347     virtual long Read (void *buffer, long len);
348     virtual char *Gets(char *strbuf, int len);
GetBuffer()349     virtual const char *GetBuffer() const { return (char*)&buf[0]; }
GetArray()350     TArray<BYTE> &GetArray() { return buf; }
351 
UpdateLength()352     void UpdateLength() { Length = buf.Size(); }
353 
354 protected:
355     TArray<BYTE> buf;
356 };
357 
358 
359 #endif
360