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 __FILE_H__
24 #define __FILE_H__
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 
29 #define FORBIDDEN_SYMBOL_ALLOW_ALL
30 
31 #include "common/scummsys.h"
32 #include "common/endian.h"
33 #include "common/algorithm.h"
34 
35 namespace Common {
36 
37 enum AccessMode {
38 	kFileReadMode = 1,
39 	kFileWriteMode = 2
40 };
41 
42 class File {
43 private:
44 	::FILE *_f;
45 	const byte *_memPtr;
46 	size_t _offset, _size;
47 public:
File()48 	File() : _f(nullptr), _memPtr(nullptr), _offset(0), _size(0) {}
49 
50 	bool open(const char *filename, AccessMode mode = kFileReadMode) {
51 		_memPtr = nullptr;
52 		_f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb+");
53 		return (_f != NULL);
54 	}
open(const byte * data,uint size)55 	bool open(const byte *data, uint size) {
56 		close();
57 		_f = nullptr;
58 		_memPtr = data;
59 		_size = size;
60 		return true;
61 	}
62 
close()63 	void close() {
64 		if (_f)
65 			fclose(_f);
66 		_f = nullptr;
67 		delete[] _memPtr;
68 		_memPtr = nullptr;
69 	}
70 	int seek(int offset, int whence = SEEK_SET) {
71 		if (_f)
72 			return fseek(_f, offset, whence);
73 
74 		switch (whence) {
75 			case SEEK_SET:
76 				_offset = offset;
77 				break;
78 			case SEEK_CUR:
79 				_offset += offset;
80 				break;
81 			case SEEK_END:
82 				_offset = _size + offset;
83 				break;
84 			default:
85 				break;
86 		}
87 
88 		return _offset;
89 	}
skip(int offset)90 	void skip(int offset) {
91 		if (_f)
92 			fseek(_f, offset, SEEK_CUR);
93 		else
94 			_offset += offset;
95 	}
read(void * buffer,size_t len)96 	long read(void *buffer, size_t len) {
97 		if (_f)
98 			return fread(buffer, 1, len, _f);
99 
100 		uint bytesToRead = CLIP(len, (size_t)0, _size - _offset);
101 		memcpy(buffer, &_memPtr[_offset], bytesToRead);
102 		_offset += bytesToRead;
103 		return bytesToRead;
104 	}
write(const void * buffer,size_t len)105 	void write(const void *buffer, size_t len) {
106 		assert(_f);
107 		fwrite(buffer, 1, len, _f);
108 	}
write(File & src,size_t len)109 	void write(File &src, size_t len) {
110 		for (size_t idx = 0; idx < len; ++idx)
111 			writeByte(src.readByte());
112 	}
readByte()113 	byte readByte() {
114 		byte v;
115 		read(&v, sizeof(byte));
116 		return v;
117 	}
readWord()118 	uint16 readWord() {
119 		uint16 v;
120 		read(&v, sizeof(uint16));
121 		return FROM_LE_16(v);
122 	}
readLong()123 	uint readLong() {
124 		uint v;
125 		read(&v, sizeof(uint));
126 		return FROM_LE_32(v);
127 	}
128 
readUint16BE()129 	uint readUint16BE() {
130 		uint16 v;
131 		read(&v, sizeof(uint16));
132 		return FROM_BE_16(v);
133 	}
readUint16LE()134 	uint readUint16LE() {
135 		uint16 v;
136 		read(&v, sizeof(uint16));
137 		return FROM_LE_16(v);
138 	}
readUint32BE()139 	uint readUint32BE() {
140 		uint32 v;
141 		read(&v, sizeof(uint32));
142 		return FROM_BE_32(v);
143 	}
readUint32LE()144 	uint readUint32LE() {
145 		uint32 v;
146 		read(&v, sizeof(uint32));
147 		return FROM_LE_32(v);
148 	}
149 
writeByte(byte v)150 	void writeByte(byte v) {
151 		write(&v, sizeof(byte));
152 	}
writeByte(byte v,int len)153 	void writeByte(byte v, int len) {
154 		byte *b = new byte[len];
155 		memset(b, v, len);
156 		write(b, len);
157 		delete[] b;
158 	}
writeWord(uint16 v)159 	void writeWord(uint16 v) {
160 		uint16 vTemp = TO_LE_16(v);
161 		write(&vTemp, sizeof(uint16));
162 	}
writeLong(uint v)163 	void writeLong(uint v) {
164 		uint vTemp = TO_LE_32(v);
165 		write(&vTemp, sizeof(uint));
166 	}
writeString(const char * msg)167 	void writeString(const char *msg) {
168 		if (!msg) {
169 			writeByte(0);
170 		} else {
171 			do {
172 				writeByte(*msg);
173 			} while (*msg++);
174 		}
175 	}
writeString(File & src)176 	void writeString(File &src) {
177 		char c;
178 		do {
179 			c = src.readByte();
180 			writeByte(c);
181 		} while (c);
182 	}
pos()183 	uint pos() const {
184 		if (_f)
185 			return ftell(_f);
186 		else
187 			return _offset;
188 	}
size()189 	uint size() const {
190 		if (_f) {
191 			uint currentPos = pos();
192 			fseek(_f, 0, SEEK_END);
193 			uint result = pos();
194 			fseek(_f, currentPos, SEEK_SET);
195 			return result;
196 		} else if (_memPtr) {
197 			return _size;
198 		} else {
199 			return 0;
200 		}
201 	}
eof()202 	bool eof() const {
203 		if (_f)
204 			return feof(_f) != 0;
205 		else if (_memPtr)
206 			return _offset >= _size;
207 		return false;
208 	}
209 };
210 
211 }
212 
213 #endif