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