📄 inflate.c
字号:
#include "u.h"#include "lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include <flate.h>typedef struct Biobuf Biobuf;struct Biobuf{ uchar *bp; uchar *p; uchar *ep;};static int header(Biobuf*);static int trailer(Biobuf*, Biobuf*);static int getc(void*);static ulong offset(Biobuf*);static int crcwrite(void *out, void *buf, int n);static ulong get4(Biobuf *b);static ulong Boffset(Biobuf *bp);/* GZIP flags */enum { Ftext= (1<<0), Fhcrc= (1<<1), Fextra= (1<<2), Fname= (1<<3), Fcomment= (1<<4), GZCRCPOLY = 0xedb88320UL,};static ulong *crctab;static ulong crc;intgunzip(uchar *out, int outn, uchar *in, int inn){ Biobuf bin, bout; int err; crc = 0; crctab = mkcrctab(GZCRCPOLY); err = inflateinit(); if(err != FlateOk) print("inflateinit failed: %s\n", flateerr(err)); bin.bp = bin.p = in; bin.ep = in+inn; bout.bp = bout.p = out; bout.ep = out+outn; err = header(&bin); if(err != FlateOk) return err; err = inflate(&bout, crcwrite, &bin, getc); if(err != FlateOk) print("inflate failed: %s\n", flateerr(err)); err = trailer(&bout, &bin); if(err != FlateOk) return err; return Boffset(&bout);}static intheader(Biobuf *bin){ int i, flag; if(getc(bin) != 0x1f || getc(bin) != 0x8b){ print("bad magic\n"); return FlateCorrupted; } if(getc(bin) != 8){ print("unknown compression type\n"); return FlateCorrupted; } flag = getc(bin); /* mod time */ get4(bin); /* extra flags */ getc(bin); /* OS type */ getc(bin); if(flag & Fextra) for(i=getc(bin); i>0; i--) getc(bin); /* name */ if(flag&Fname) while(getc(bin) != 0) ; /* comment */ if(flag&Fcomment) while(getc(bin) != 0) ; /* crc16 */ if(flag&Fhcrc) { getc(bin); getc(bin); } return FlateOk;}static inttrailer(Biobuf *bout, Biobuf *bin){ /* crc32 */ ulong x; x = get4(bin); if(crc != x){ print("crc mismatch %lux %lux\n", crc, x); return FlateCorrupted; } /* length */ if(get4(bin) != Boffset(bout)){ print("bad output len\n"); return FlateCorrupted; } return FlateOk;}static ulongget4(Biobuf *b){ ulong v; int i, c; v = 0; for(i = 0; i < 4; i++){ c = getc(b); v |= c << (i * 8); } return v;}static intgetc(void *in){ Biobuf *bp = in; if((bp->p - bp->bp) % 10000 == 0) print("."); if(bp->p >= bp->ep) return -1; return *bp->p++;}static ulongBoffset(Biobuf *bp){ return bp->p - bp->bp;}static intcrcwrite(void *out, void *buf, int n){ Biobuf *bp; crc = blockcrc(crctab, crc, buf, n); bp = out; if(n > bp->ep-bp->p) n = bp->ep-bp->p; memmove(bp->p, buf, n); bp->p += n; return n;}#undef malloc#undef freestatic ulong ibrkp = ~0;void *malloc(ulong n){ ulong rv; if(ibrkp == ~0) ibrkp = ((ulong)end)+1024*1024; n = (n+3)>>2; n <<= 2; rv = ibrkp; ibrkp += n; return (void*)rv;}voidfree(void *){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -