xref: /plan9/sys/src/libflate/inflatezlibblock.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 Block	Block;
7*80ee5cbfSDavid du Colombier 
8*80ee5cbfSDavid du Colombier struct Block
9*80ee5cbfSDavid du Colombier {
10*80ee5cbfSDavid du Colombier 	uchar	*pos;
11*80ee5cbfSDavid du Colombier 	uchar	*limit;
12*80ee5cbfSDavid du Colombier };
13*80ee5cbfSDavid du Colombier 
14*80ee5cbfSDavid du Colombier static int
blgetc(void * vb)15*80ee5cbfSDavid du Colombier blgetc(void *vb)
16*80ee5cbfSDavid du Colombier {
17*80ee5cbfSDavid du Colombier 	Block *b;
18*80ee5cbfSDavid du Colombier 
19*80ee5cbfSDavid du Colombier 	b = vb;
20*80ee5cbfSDavid du Colombier 	if(b->pos >= b->limit)
21*80ee5cbfSDavid du Colombier 		return -1;
22*80ee5cbfSDavid du Colombier 	return *b->pos++;
23*80ee5cbfSDavid du Colombier }
24*80ee5cbfSDavid du Colombier 
25*80ee5cbfSDavid du Colombier static int
blwrite(void * vb,void * buf,int n)26*80ee5cbfSDavid du Colombier blwrite(void *vb, void *buf, int n)
27*80ee5cbfSDavid du Colombier {
28*80ee5cbfSDavid du Colombier 	Block *b;
29*80ee5cbfSDavid du Colombier 
30*80ee5cbfSDavid du Colombier 	b = vb;
31*80ee5cbfSDavid du Colombier 
32*80ee5cbfSDavid du Colombier 	if(n > b->limit - b->pos)
33*80ee5cbfSDavid du Colombier 		n = b->limit - b->pos;
34*80ee5cbfSDavid du Colombier 	memmove(b->pos, buf, n);
35*80ee5cbfSDavid du Colombier 	b->pos += n;
36*80ee5cbfSDavid du Colombier 	return n;
37*80ee5cbfSDavid du Colombier }
38*80ee5cbfSDavid du Colombier 
39*80ee5cbfSDavid du Colombier int
inflatezlibblock(uchar * dst,int dsize,uchar * src,int ssize)40*80ee5cbfSDavid du Colombier inflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize)
41*80ee5cbfSDavid du Colombier {
42*80ee5cbfSDavid du Colombier 	Block bd, bs;
43*80ee5cbfSDavid du Colombier 	int ok;
44*80ee5cbfSDavid du Colombier 
45*80ee5cbfSDavid du Colombier 	if(ssize < 6)
46*80ee5cbfSDavid du Colombier 		return FlateInputFail;
47*80ee5cbfSDavid du Colombier 
48*80ee5cbfSDavid du Colombier 	if(((src[0] << 8) | src[1]) % 31)
49*80ee5cbfSDavid du Colombier 		return FlateCorrupted;
50*80ee5cbfSDavid du Colombier 	if((src[0] & ZlibMeth) != ZlibDeflate
51*80ee5cbfSDavid du Colombier 	|| (src[0] & ZlibCInfo) > ZlibWin32k)
52*80ee5cbfSDavid du Colombier 		return FlateCorrupted;
53*80ee5cbfSDavid du Colombier 
54*80ee5cbfSDavid du Colombier 	bs.pos = src + 2;
55*80ee5cbfSDavid du Colombier 	bs.limit = src + ssize - 6;
56*80ee5cbfSDavid du Colombier 
57*80ee5cbfSDavid du Colombier 	bd.pos = dst;
58*80ee5cbfSDavid du Colombier 	bd.limit = dst + dsize;
59*80ee5cbfSDavid du Colombier 
60*80ee5cbfSDavid du Colombier 	ok = inflate(&bd, blwrite, &bs, blgetc);
61*80ee5cbfSDavid du Colombier 	if(ok != FlateOk)
62*80ee5cbfSDavid du Colombier 		return ok;
63*80ee5cbfSDavid du Colombier 
64*80ee5cbfSDavid du Colombier 	if(adler32(1, dst, bs.pos - dst) != ((bs.pos[0] << 24) | (bs.pos[1] << 16) | (bs.pos[2] << 8) | bs.pos[3]))
65*80ee5cbfSDavid du Colombier 		return FlateCorrupted;
66*80ee5cbfSDavid du Colombier 
67*80ee5cbfSDavid du Colombier 	return bd.pos - dst;
68*80ee5cbfSDavid du Colombier }
69