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