2
Copyright (C) 2003-2004 Douglas Thain and the University of Wisconsin
3
Copyright (C) 2005- The University of Notre Dame
4
This software is distributed under the GNU General Public License.
5
See the file COPYING for details.
9
#include "pfs_service.h"
11
#include "pfs_file_gzip.h"
27
#define BUFFER_SIZE 65536
31
#define STATE_BROKEN 2
33
#define GZIP_MAGIC1 0x1f
34
#define GZIP_MAGIC2 0x8b
36
#define GZIP_DEFLATE 8
38
#define GZIP_FLAG_FTEXT 1
39
#define GZIP_FLAG_FHCRC 2
40
#define GZIP_FLAG_FNAME 4
41
#define GZIP_FLAG_COMMENT 8
43
class pfs_file_gzip : public pfs_file
48
unsigned char buffer[BUFFER_SIZE];
49
pfs_off_t compressed_file_pointer;
52
unsigned char read_byte() {
54
file->read(&c,1,compressed_file_pointer++);
58
int read_gzip_header() {
63
if(read_byte()!=GZIP_MAGIC1) goto broken;
64
if(read_byte()!=GZIP_MAGIC2) goto broken;
65
if(read_byte()!=GZIP_DEFLATE) goto broken;
69
for(i=0;i<6;i++) read_byte();
71
if(flags&GZIP_FLAG_FTEXT) {
72
length = (read_byte() | (((unsigned int)read_byte())<8));
73
for(i=0;i<length;i++) read_byte();
76
if(flags&GZIP_FLAG_FNAME) {
77
while(read_byte()!=0) {}
80
if(flags&GZIP_FLAG_COMMENT) {
81
while(read_byte()!=0) {}
84
if(flags&GZIP_FLAG_FHCRC) {
89
inflateInit2(zstream,-15);
101
pfs_file_gzip( pfs_file *f ) : pfs_file(f->get_name()) {
103
zstream = (z_streamp) malloc(sizeof(*zstream));
104
memset(zstream,0,sizeof(*zstream));
119
pfs_ssize_t read( void *data, pfs_size_t length, pfs_off_t offset )
121
unsigned char *cdata = (unsigned char*)data;
122
pfs_ssize_t total = 0;
123
pfs_ssize_t actual = 0;
126
if(state==STATE_RESET) {
130
if(state==STATE_BROKEN) {
136
if(zstream->avail_in==0) {
137
actual = file->read(buffer,BUFFER_SIZE,compressed_file_pointer);
140
compressed_file_pointer += actual;
141
zstream->next_in = buffer;
142
zstream->avail_in = actual;
145
zstream->next_out = cdata;
146
zstream->avail_out = length;
148
zresult = inflate(zstream,Z_SYNC_FLUSH);
149
if(zresult==Z_OK || zresult==Z_STREAM_END) {
150
actual = length-zstream->avail_out;
160
debug(D_NOTICE,"decompression error %d on file %s",zresult,get_name()->logical_name);
178
pfs_ssize_t write( const void *data, pfs_size_t length, pfs_off_t offset )
184
int fstat( struct pfs_stat *buf )
186
return file->fstat(buf);
189
int fstatfs( struct pfs_statfs *buf )
191
return file->fstatfs(buf);
194
int ftruncate( pfs_size_t length )
196
return file->ftruncate(length);
201
return file->fsync();
204
int fcntl( int cmd, void *arg )
206
return file->fcntl(cmd,arg);
209
int ioctl( int cmd, void *arg )
211
return file->ioctl(cmd,arg);
214
int fchmod( mode_t mode )
216
return file->fchmod(mode);
219
int fchown( uid_t uid, gid_t gid )
221
return file->fchown(uid,gid);
226
return file->flock(op);
229
void * mmap( void *start, pfs_size_t length, int prot, int flags, off_t offset )
231
return file->mmap(start,length,prot,flags,offset);
234
struct dirent * fdreaddir( pfs_off_t offset, pfs_off_t *next_offset )
236
return file->fdreaddir(offset,next_offset);
239
pfs_name * get_name()
241
return file->get_name();
244
pfs_ssize_t get_size()
246
return file->get_size();
251
return file->get_real_fd();
254
int get_local_name( char *n )
256
return file->get_local_name(n);
265
pfs_file * pfs_gzip_open( pfs_file *file, int flags, int mode )
267
return new pfs_file_gzip(file);