/* Copyright (C) 2003 John Whitney
*
* 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.
*
* Author: John Whitney <jjw@linuxmail.org>
*/
#include <zlib.h>
#include <bzlib.h>
class IStream {
public:
virtual int read(void *data, int num) = 0;
template<class T>
int get(T &data) {return read(&data, sizeof(data));}
};
class OStream {
public:
virtual int write(const void *data, int num) = 0;
template<class T>
int put(const T &data) {return write(&data, sizeof(data));}
};
class IFStream : public IStream {
FILE *file;
public:
IFStream(const char *fname) {file = fopen(fname, "r");}
virtual ~IFStream() {if (!bad()) fclose(file);}
virtual int read(void *data, int num) {
return fread(data, 1, num, file);
}
bool bad() {return file==NULL;}
};
unsigned read_word(IStream &f) {
unsigned char b, b2;
f.get(b);
f.get(b2);
return (b2<<8)+b;
}
unsigned read_dword(IStream &f) {
unsigned low = read_word(f);
return (read_word(f)<<16)+low;
}
void write_word(FILE *f, unsigned number) {
unsigned char b = number&255;
fwrite(&b, 1, 1, f);
b = number>>8;
fwrite(&b, 1, 1, f);
}
void write_dword(FILE *f, unsigned number) {
write_word(f, number&65535);
write_word(f, number>>16);
}
class OFStream : public OStream {
void *file;
public:
OFStream(const char *fname) {file = fopen(fname, "w");}
virtual ~OFStream() {fclose((FILE*)file);}
virtual int write(const void *data, int num) {
return fwrite(data, 1, num, (FILE*)file);
}
bool bad() {return file==NULL;}
};
class GZ_IFStream : public IStream {
void *file;
public:
GZ_IFStream(char *fname) {file = gzopen(fname, "rb");}
virtual ~GZ_IFStream() {if (!bad()) gzclose(file);}
virtual int read(void *data, int num) {return gzread(file, data, num);}
bool bad() {return (file==NULL);}
};
class GZ_OFStream : public OStream {
void *file;
public:
GZ_OFStream(char *fname) {file = gzopen(fname, "wb");}
virtual ~GZ_OFStream() {gzclose(file);}
virtual int write(const void *data, int num) {return gzwrite(file, (voidp)data, num);}
bool bad() {return (file==NULL);}
};
class BZ_IFStream : public IStream {
void *file;
public:
BZ_IFStream(char *fname) {file = BZ2_bzopen(fname, "rb");}
virtual ~BZ_IFStream() {if (!bad()) BZ2_bzclose(file);}
virtual int read(void *data, int num) {return BZ2_bzread(file, data, num);}
bool bad() {return (file==NULL);}
};
class Injectable_IStream : public IStream {
struct Injected {
void *buf;
void *start;
unsigned num;
Injected(void *buf, unsigned num) {
this->buf = start = new char[num];
memcpy(start, buf, num);
this->num = num;
}
};
IStream &f;
DList<Injected> list;
public:
Injectable_IStream(IStream &F) : f(F) {}
virtual void inject(void *data, int num) {
void *d = new char[num];
memcpy(d, data, num);
list.push_front(new Injected(data, num));
}
virtual int read(void *vdata, int num) {
int numread=0;
char *data = (char*)vdata;
while (!list.empty() && num >= list.first->obj->num) {
unsigned numbuf = list.first->obj->num;
memcpy(data, list.first->obj->buf, numbuf);
data+=numbuf;
num-=numbuf;
numread+=numbuf;
delete (char*)list.first->obj->start;
delete list.first->obj;
list.erase(list.first);
}
if (!list.empty()) {
//char *cbuf;
memcpy(data, list.first->obj->buf, num);
list.first->obj->num-=num;
//cbuf = (char*)list.first->obj->buf;
list.first->obj->buf=(char*)list.first->obj->buf+num;
//cbuf+=num;
numread+=num;
} else {
numread+=f.read(data, num);
}
return numread;
}
};
syntax highlighted by Code2HTML, v. 0.9.1