Files
2010-11-11 20:44:02 +02:00

223 lines
4.2 KiB
C++

/* REminiscence - Flashback interpreter
* Copyright (C) 2005-2007 Gregory Montoir
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "zlib.h"
#include "file.h"
struct File_impl {
bool _ioErr;
File_impl() : _ioErr(false) {}
virtual bool open(const char *path, const char *mode) = 0;
virtual void close() = 0;
virtual uint32 size() = 0;
virtual void seek(int32 off) = 0;
virtual void read(void *ptr, uint32 len) = 0;
virtual void write(void *ptr, uint32 len) = 0;
};
struct stdFile : File_impl {
FILE *_fp;
stdFile() : _fp(0) {}
bool open(const char *path, const char *mode) {
_ioErr = false;
_fp = fopen(path, mode);
return (_fp != 0);
}
void close() {
if (_fp) {
fclose(_fp);
_fp = 0;
}
}
uint32 size() {
uint32 sz = 0;
if (_fp) {
int pos = ftell(_fp);
fseek(_fp, 0, SEEK_END);
sz = ftell(_fp);
fseek(_fp, pos, SEEK_SET);
}
return sz;
}
void seek(int32 off) {
if (_fp) {
fseek(_fp, off, SEEK_SET);
}
}
void read(void *ptr, uint32 len) {
if (_fp) {
uint32 r = fread(ptr, 1, len, _fp);
if (r != len) {
_ioErr = true;
}
}
}
void write(void *ptr, uint32 len) {
if (_fp) {
uint32 r = fwrite(ptr, 1, len, _fp);
if (r != len) {
_ioErr = true;
}
}
}
};
struct zlibFile : File_impl {
gzFile _fp;
zlibFile() : _fp(0) {}
bool open(const char *path, const char *mode) {
_ioErr = false;
_fp = gzopen(path, mode);
return (_fp != 0);
}
void close() {
if (_fp) {
gzclose(_fp);
_fp = 0;
}
}
uint32 size() {
uint32 sz = 0;
if (_fp) {
int pos = gztell(_fp);
gzseek(_fp, 0, SEEK_END);
sz = gztell(_fp);
gzseek(_fp, pos, SEEK_SET);
}
return sz;
}
void seek(int32 off) {
if (_fp) {
gzseek(_fp, off, SEEK_SET);
}
}
void read(void *ptr, uint32 len) {
if (_fp) {
uint32 r = gzread(_fp, ptr, len);
if (r != len) {
_ioErr = true;
}
}
}
void write(void *ptr, uint32 len) {
if (_fp) {
uint32 r = gzwrite(_fp, ptr, len);
if (r != len) {
_ioErr = true;
}
}
}
};
File::File(bool gzipped) {
if (gzipped) {
_impl = new zlibFile;
} else {
_impl = new stdFile;
}
}
File::~File() {
_impl->close();
delete _impl;
}
bool File::open(const char *filename, const char *directory, const char *mode) {
_impl->close();
char buf[512];
sprintf(buf, "%s/%s", directory, filename);
char *p = buf + strlen(directory) + 1;
string_lower(p);
bool opened = _impl->open(buf, mode);
if (!opened) { // let's try uppercase
string_upper(p);
opened = _impl->open(buf, mode);
}
return opened;
}
void File::close() {
_impl->close();
}
bool File::ioErr() const {
return _impl->_ioErr;
}
uint32 File::size() {
return _impl->size();
}
void File::seek(int32 off) {
_impl->seek(off);
}
void File::read(void *ptr, uint32 len) {
_impl->read(ptr, len);
}
uint8 File::readByte() {
uint8 b;
read(&b, 1);
return b;
}
uint16 File::readUint16LE() {
uint8 lo = readByte();
uint8 hi = readByte();
return (hi << 8) | lo;
}
uint32 File::readUint32LE() {
uint16 lo = readUint16LE();
uint16 hi = readUint16LE();
return (hi << 16) | lo;
}
uint16 File::readUint16BE() {
uint8 hi = readByte();
uint8 lo = readByte();
return (hi << 8) | lo;
}
uint32 File::readUint32BE() {
uint16 hi = readUint16BE();
uint16 lo = readUint16BE();
return (hi << 16) | lo;
}
void File::write(void *ptr, uint32 len) {
_impl->write(ptr, len);
}
void File::writeByte(uint8 b) {
write(&b, 1);
}
void File::writeUint16BE(uint16 n) {
writeByte(n >> 8);
writeByte(n & 0xFF);
}
void File::writeUint32BE(uint32 n) {
writeUint16BE(n >> 16);
writeUint16BE(n & 0xFFFF);
}