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