12 unsigned char *window
;
13 size_t buffer_size
, window_cap
, buffer_cap
;
15 void fill_buffer (void) {
18 for (i
= window_cap
+ buffer_size
; i
< window_cap
+ buffer_cap
; i
++) {
23 window
[i
] = (unsigned char) c
;
28 void shift_buffer (unsigned int shift
) {
29 memmove (&window
[0], &window
[shift
], window_cap
+ buffer_cap
- shift
);
33 unsigned int comlen(const unsigned char *str1
34 , const unsigned char *str2
35 , unsigned int limit
) {
37 while (*str1
++ == *str2
++ && len
< limit
)
42 struct pair
find_match (void) {
45 unsigned int dist
, len
;
49 for (i
= 0; i
< window_cap
; i
++) {
50 clen
= comlen(&window
[i
], &window
[window_cap
], buffer_size
- 1);
53 dist
= window_cap
- i
;
56 match
.distance
= len
? dist
: 0;
61 void write_pair (struct pair pair
) {
63 c
= pair
.distance
% 256;
65 c
= (pair
.distance
/ 256) | (pair
.length
<< 3);
69 void compress (void) {
73 match
= find_match ();
74 shift_buffer (match
.length
+ 1);
76 putchar ((int) window
[window_cap
- 1]);
81 int read_pair (struct pair
*pair
) {
91 fprintf(stderr
, "%s: Unexpected end of file.\n", progname
);
94 tmp
= tmp
| ((c
& 0x07) << 8);
95 pair
-> distance
= tmp
;
96 pair
-> length
= c
>> 3;
100 void decompress (void) {
104 while (read_pair (&pair
)) {
107 fprintf(stderr
, "%s: Unexpected end of file.\n", progname
);
110 for (i
= 0; i
< pair
.length
; i
++) {
111 window
[window_cap
+ i
] = window
[window_cap
- pair
.distance
+ i
];
114 window
[window_cap
+ buffer_size
++] = (unsigned char) c
;
115 for (i
= 0; i
< buffer_size
; i
++) {
116 putchar ((int) window
[window_cap
+i
]);
118 shift_buffer (buffer_size
);
122 int main (int argc
, char **argv
) {
126 window
= (unsigned char *) malloc (sizeof (unsigned char)
127 * (window_cap
+ buffer_cap
));
128 if (window
== NULL
) {
129 fprintf(stderr
, "%s: Can not allocate memory.\n", progname
);
132 memset (window
, 0, window_cap
+ buffer_cap
);
133 if (argc
== 2 && strcmp("-d", argv
[1]) == 0) {
135 } else if (argc
== 1) {
138 fprintf(stderr
, "Usage: %s [-d]\n", progname
);