xref: /plan9/sys/src/libflate/inflatezlib.c (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
1*80ee5cbfSDavid du Colombier #include <u.h>
2*80ee5cbfSDavid du Colombier #include <libc.h>
3*80ee5cbfSDavid du Colombier #include <flate.h>
4*80ee5cbfSDavid du Colombier #include "zlib.h"
5*80ee5cbfSDavid du Colombier 
6*80ee5cbfSDavid du Colombier typedef struct ZWrite	ZWrite;
7*80ee5cbfSDavid du Colombier 
8*80ee5cbfSDavid du Colombier struct ZWrite
9*80ee5cbfSDavid du Colombier {
10*80ee5cbfSDavid du Colombier 	ulong	adler;
11*80ee5cbfSDavid du Colombier 	void	*wr;
12*80ee5cbfSDavid du Colombier 	int	(*w)(void*, void*, int);
13*80ee5cbfSDavid du Colombier };
14*80ee5cbfSDavid du Colombier 
15*80ee5cbfSDavid du Colombier static int
zlwrite(void * vzw,void * buf,int n)16*80ee5cbfSDavid du Colombier zlwrite(void *vzw, void *buf, int n)
17*80ee5cbfSDavid du Colombier {
18*80ee5cbfSDavid du Colombier 	ZWrite *zw;
19*80ee5cbfSDavid du Colombier 
20*80ee5cbfSDavid du Colombier 	zw = vzw;
21*80ee5cbfSDavid du Colombier 	zw->adler = adler32(zw->adler, buf, n);
22*80ee5cbfSDavid du Colombier 	n = (*zw->w)(zw->wr, buf, n);
23*80ee5cbfSDavid du Colombier 	if(n <= 0)
24*80ee5cbfSDavid du Colombier 		return n;
25*80ee5cbfSDavid du Colombier 	return n;
26*80ee5cbfSDavid du Colombier }
27*80ee5cbfSDavid du Colombier 
28*80ee5cbfSDavid du Colombier int
inflatezlib(void * wr,int (* w)(void *,void *,int),void * getr,int (* get)(void *))29*80ee5cbfSDavid du Colombier inflatezlib(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
30*80ee5cbfSDavid du Colombier {
31*80ee5cbfSDavid du Colombier 	ZWrite zw;
32*80ee5cbfSDavid du Colombier 	ulong v;
33*80ee5cbfSDavid du Colombier 	int c, i;
34*80ee5cbfSDavid du Colombier 
35*80ee5cbfSDavid du Colombier 	c = (*get)(getr);
36*80ee5cbfSDavid du Colombier 	if(c < 0)
37*80ee5cbfSDavid du Colombier 		return FlateInputFail;
38*80ee5cbfSDavid du Colombier 	i = (*get)(getr);
39*80ee5cbfSDavid du Colombier 	if(i < 0)
40*80ee5cbfSDavid du Colombier 		return FlateInputFail;
41*80ee5cbfSDavid du Colombier 
42*80ee5cbfSDavid du Colombier 	if(((c << 8) | i) % 31)
43*80ee5cbfSDavid du Colombier 		return FlateCorrupted;
44*80ee5cbfSDavid du Colombier 	if((c & ZlibMeth) != ZlibDeflate
45*80ee5cbfSDavid du Colombier 	|| (c & ZlibCInfo) > ZlibWin32k)
46*80ee5cbfSDavid du Colombier 		return FlateCorrupted;
47*80ee5cbfSDavid du Colombier 
48*80ee5cbfSDavid du Colombier 	zw.wr = wr;
49*80ee5cbfSDavid du Colombier 	zw.w = w;
50*80ee5cbfSDavid du Colombier 	zw.adler = 1;
51*80ee5cbfSDavid du Colombier 	i = inflate(&zw, zlwrite, getr, get);
52*80ee5cbfSDavid du Colombier 	if(i != FlateOk)
53*80ee5cbfSDavid du Colombier 		return i;
54*80ee5cbfSDavid du Colombier 
55*80ee5cbfSDavid du Colombier 	v = 0;
56*80ee5cbfSDavid du Colombier 	for(i = 0; i < 4; i++){
57*80ee5cbfSDavid du Colombier 		c = (*get)(getr);
58*80ee5cbfSDavid du Colombier 		if(c < 0)
59*80ee5cbfSDavid du Colombier 			return FlateInputFail;
60*80ee5cbfSDavid du Colombier 		v = (v << 8) | c;
61*80ee5cbfSDavid du Colombier 	}
62*80ee5cbfSDavid du Colombier 	if(zw.adler != v)
63*80ee5cbfSDavid du Colombier 		return FlateCorrupted;
64*80ee5cbfSDavid du Colombier 
65*80ee5cbfSDavid du Colombier 	return FlateOk;
66*80ee5cbfSDavid du Colombier }
67