]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libflate/inflatezlib.c
qer(8): correct man page example (thanks, kenji)
[plan9front.git] / sys / src / libflate / inflatezlib.c
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
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
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 }