1 /* "Species" - a CoreWars evolver.  Copyright (C) 2003 'Varfar'
2  *
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 1, or (at your option) any later
6  * version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 675 Mass Ave, Cambridge, MA 02139, USA.
16  */
17 
18 #include "compress.h"
19 
20 #include <zlib.h>
21 
panic(const char * reason)22 static panic(const char *reason) {
23 	fprintf(stderr,"\ncompress ERROR: %s\n",reason);
24 	exit(1);
25 }
26 
27 static unsigned long long physical_bytes, logical_bytes;
28 // metrics
init_compress_metrics()29 void init_compress_metrics() {
30 	physical_bytes = 0;
31 	logical_bytes = 0;
32 }
33 
get_physical_bytes()34 unsigned long long get_physical_bytes() { return physical_bytes; }
get_logical_bytes()35 unsigned long long get_logical_bytes() { return logical_bytes; }
36 
37 static comp_buf_t temp, check;
38 
block_compress(comp_buf_t * src)39 void block_compress(comp_buf_t *src) {
40 	int i, zret;
41 	if(src->len == 0) return;
42 	// compress it
43 	if(src->len > COMPRESS_BUFFER) panic("c1");
44 	temp.len = COMPRESS_SAFE_BUFFER;
45 	zret = compress(temp.buf,&temp.len,src->buf,src->len); // try to compress
46 	if(zret != Z_OK) {
47 		fprintf(stderr,"Z_ERROR: %s\n",zError(zret));
48 		panic("c2");
49 	}
50 	// write it
51 	if(1 != fwrite(&temp.len,sizeof(uLongf),1,src->f)) panic("c3"); // block len
52 	if(temp.len != fwrite(temp.buf,sizeof(Bytef),temp.len,src->f)) panic("c4"); // compressed data
53 	// done
54 	//fflush(src->f);
55 	physical_bytes += temp.len;
56 	logical_bytes += src->len;
57 }
58 
flush_compressed(comp_buf_t * src)59 void flush_compressed(comp_buf_t *src) {
60 	block_compress(src);
61 	src->len = 0;
62 }
63 
write_compressed(comp_buf_t * src,Bytef ch)64 void write_compressed(comp_buf_t *src,Bytef ch) {
65 	src->buf[src->len++] = ch;
66 	if(src->len == COMPRESS_BUFFER)
67 		flush_compressed(src);
68 }
69 
block_decompress(comp_buf_t * dest)70 void block_decompress(comp_buf_t *dest) {
71 	int zret;
72 	// read block
73 	if(1 != fread(&temp.len,sizeof(uLongf),1,dest->f)) { // block len? not successful suggests eof
74 		dest->len = 0;
75 		return;
76 	}
77 	if(temp.len > COMPRESS_SAFE_BUFFER) panic("d1");
78 	if(temp.len != fread(temp.buf,sizeof(Bytef),temp.len,dest->f)) panic("d2"); // compressed data
79 	// decompress it
80 	dest->len = COMPRESS_SAFE_BUFFER;
81 	zret = uncompress(dest->buf,&dest->len,temp.buf,temp.len);
82 	if(zret != Z_OK) {
83 		fprintf(stderr,"Z_ERROR: %s\n",zError(zret));
84 		panic("d3");
85 	}
86 	// done
87 	physical_bytes += temp.len;
88 	logical_bytes += dest->len;
89 }
90 
91