diff -r 4252bfc396fc -r d382dacfd73f emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflate.java --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflate.java Tue Feb 26 14:55:55 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,727 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; - -final class Inflate{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - - // preset dictionary flag in zlib header - static final private int PRESET_DICT=0x20; - - static final int Z_NO_FLUSH=0; - static final int Z_PARTIAL_FLUSH=1; - static final int Z_SYNC_FLUSH=2; - static final int Z_FULL_FLUSH=3; - static final int Z_FINISH=4; - - static final private int Z_DEFLATED=8; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final private int METHOD=0; // waiting for method byte - static final private int FLAG=1; // waiting for flag byte - static final private int DICT4=2; // four dictionary check bytes to go - static final private int DICT3=3; // three dictionary check bytes to go - static final private int DICT2=4; // two dictionary check bytes to go - static final private int DICT1=5; // one dictionary check byte to go - static final int DICT0=6; // waiting for inflateSetDictionary - static final private int BLOCKS=7; // decompressing blocks - static final private int CHECK4=8; // four check bytes to go - static final private int CHECK3=9; // three check bytes to go - static final private int CHECK2=10; // two check bytes to go - static final private int CHECK1=11; // one check byte to go - static final private int DONE=12; // finished check, done - static final private int BAD=13; // got an error--stay here - - static final private int HEAD=14; - static final private int LENGTH=15; - static final private int TIME=16; - static final private int OS=17; - static final private int EXLEN=18; - static final private int EXTRA=19; - static final private int NAME=20; - static final private int COMMENT=21; - static final private int HCRC=22; - static final private int FLAGS=23; - - int mode; // current inflate mode - - // mode dependent information - int method; // if FLAGS, method byte - - // if CHECK, check values to compare - long was = -1; // computed check value - long need; // stream check value - - // if BAD, inflateSync's marker bytes count - int marker; - - // mode independent information - int wrap; // flag for no wrapper - int wbits; // log2(window size) (8..15, defaults to 15) - - InfBlocks blocks; // current inflate_blocks state - - private final ZStream z; - - private int flags; - - private int need_bytes = -1; - private byte[] crcbuf=new byte[4]; - - GZIPHeader gheader = null; - - int inflateReset(){ - if(z == null) return Z_STREAM_ERROR; - - z.total_in = z.total_out = 0; - z.msg = null; - this.mode = HEAD; - this.need_bytes = -1; - this.blocks.reset(); - return Z_OK; - } - - int inflateEnd(){ - if(blocks != null){ - blocks.free(); - } - return Z_OK; - } - - Inflate(ZStream z){ - this.z=z; - } - - int inflateInit(int w){ - z.msg = null; - blocks = null; - - // handle undocumented wrap option (no zlib header or check) - wrap = 0; - if(w < 0){ - w = - w; - } - else { - wrap = (w >> 4) + 1; - if(w < 48) - w &= 15; - } - - if(w<8 ||w>15){ - inflateEnd(); - return Z_STREAM_ERROR; - } - if(blocks != null && wbits != w){ - blocks.free(); - blocks=null; - } - - // set window size - wbits=w; - - this.blocks=new InfBlocks(z, 1<>8))&0xff; - - if((wrap&1)==0 || // check if zlib header allowed - (((this.method << 8)+b) % 31)!=0){ - this.mode = BAD; - z.msg = "incorrect header check"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if((this.method&0xf)!=Z_DEFLATED){ - this.mode = BAD; - z.msg="unknown compression method"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if((this.method>>4)+8>this.wbits){ - this.mode = BAD; - z.msg="invalid window size"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - z.adler=new Adler32(); - - if((b&PRESET_DICT)==0){ - this.mode = BLOCKS; - break; - } - this.mode = DICT4; - case DICT4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=DICT3; - case DICT3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode=DICT2; - case DICT2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode=DICT1; - case DICT1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need += (z.next_in[z.next_in_index++]&0xffL); - z.adler.reset(this.need); - this.mode = DICT0; - return Z_NEED_DICT; - case DICT0: - this.mode = BAD; - z.msg = "need dictionary"; - this.marker = 0; // can try inflateSync - return Z_STREAM_ERROR; - case BLOCKS: - r = this.blocks.proc(r); - if(r == Z_DATA_ERROR){ - this.mode = BAD; - this.marker = 0; // can try inflateSync - break; - } - if(r == Z_OK){ - r = f; - } - if(r != Z_STREAM_END){ - return r; - } - r = f; - this.was=z.adler.getValue(); - this.blocks.reset(); - if(this.wrap==0){ - this.mode=DONE; - break; - } - this.mode=CHECK4; - case CHECK4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=CHECK3; - case CHECK3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode = CHECK2; - case CHECK2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode = CHECK1; - case CHECK1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=(z.next_in[z.next_in_index++]&0xffL); - - if(flags!=0){ // gzip - this.need = ((this.need&0xff000000)>>24 | - (this.need&0x00ff0000)>>8 | - (this.need&0x0000ff00)<<8 | - (this.need&0x0000ffff)<<24)&0xffffffffL; - } - - if(((int)(this.was)) != ((int)(this.need))){ - z.msg = "incorrect data check"; - // chack is delayed - /* - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - */ - } - else if(flags!=0 && gheader!=null){ - gheader.crc = this.need; - } - - this.mode = LENGTH; - case LENGTH: - if (wrap!=0 && flags!=0) { - - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - - if (this.need != (z.total_out & 0xffffffffL)) { - z.msg = "incorrect length check"; - this.mode = BAD; - break; - } - z.msg = null; - } - else { - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - } - - this.mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - - case FLAGS: - - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - - flags = ((int)this.need)&0xffff; - - if ((flags & 0xff) != Z_DEFLATED) { - z.msg = "unknown compression method"; - this.mode = BAD; - break; - } - if ((flags & 0xe000)!=0) { - z.msg = "unknown header flags set"; - this.mode = BAD; - break; - } - - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - - this.mode = TIME; - - case TIME: - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null) - gheader.time = this.need; - if ((flags & 0x0200)!=0){ - checksum(4, this.need); - } - this.mode = OS; - case OS: - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.xflags = ((int)this.need)&0xff; - gheader.os = (((int)this.need)>>8)&0xff; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - this.mode = EXLEN; - case EXLEN: - if ((flags & 0x0400)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.extra = new byte[((int)this.need)&0xffff]; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = EXTRA; - - case EXTRA: - if ((flags & 0x0400)!=0) { - try { - r=readBytes(r, f); - if(gheader!=null){ - byte[] foo = tmp_array; - tmp_array=null; - if(foo.length == gheader.extra.length){ - System.arraycopy(foo, 0, gheader.extra, 0, foo.length); - } - else{ - z.msg = "bad extra field length"; - this.mode = BAD; - break; - } - } - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = NAME; - case NAME: - if ((flags & 0x0800)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.name=tmp_array; - } - tmp_array=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.name=null; - } - this.mode = COMMENT; - case COMMENT: - if ((flags & 0x1000)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.comment=tmp_array; - } - tmp_array=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.comment=null; - } - this.mode = HCRC; - case HCRC: - if ((flags & 0x0200)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.hcrc=(int)(this.need&0xffff); - } - if(this.need != (z.adler.getValue()&0xffffL)){ - this.mode = BAD; - z.msg = "header crc mismatch"; - this.marker = 5; // can't try inflateSync - break; - } - } - z.adler = new CRC32(); - - this.mode = BLOCKS; - break; - default: - return Z_STREAM_ERROR; - } - } - } - - int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(z==null || (this.mode != DICT0 && this.wrap != 0)){ - return Z_STREAM_ERROR; - } - - int index=0; - int length = dictLength; - - if(this.mode==DICT0){ - long adler_need=z.adler.getValue(); - z.adler.reset(); - z.adler.update(dictionary, 0, dictLength); - if(z.adler.getValue()!=adler_need){ - return Z_DATA_ERROR; - } - } - - z.adler.reset(); - - if(length >= (1<0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - this.need = this.need | - ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); - need_bytes--; - } - if(n==2){ - this.need&=0xffffL; - } - else if(n==4) { - this.need&=0xffffffffL; - } - need_bytes=-1; - return r; - } - class Return extends Exception{ - int r; - Return(int r){this.r=r; } - } - - private byte[] tmp_array; - private int readString(int r, int f) throws Return{ - int b=0; - byte[] arr = new byte[4092]; - int at = 0; - do { - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - if(b!=0) arr = append(arr, z.next_in[z.next_in_index], at++); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - }while(b!=0); - - tmp_array = copy(arr, at); - - return r; - } - - private int readBytes(int r, int f) throws Return{ - int b=0; - byte[] arr = new byte[4092]; - int at = 0; - while(this.need>0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - arr = append(arr, z.next_in[z.next_in_index], at++); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - this.need--; - } - - tmp_array = copy(arr, at); - - return r; - } - - private static byte[] copy(byte[] arr, int len) { - byte[] ret = new byte[len]; - org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, 0, ret, 0, len); - return ret; - } - private static byte[] append(byte[] arr, byte b, int index) { - arr[index] = b; - return arr; - } - - private void checksum(int n, long v){ - for(int i=0; i>=8; - } - z.adler.update(crcbuf, 0, n); - } - - public GZIPHeader getGZIPHeader(){ - return gheader; - } - - boolean inParsingHeader(){ - switch(mode){ - case HEAD: - case DICT4: - case DICT3: - case DICT2: - case DICT1: - case FLAGS: - case TIME: - case OS: - case EXLEN: - case EXTRA: - case NAME: - case COMMENT: - case HCRC: - return true; - default: - return false; - } - } -}