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