1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflate.java Mon Feb 25 19:00:08 2013 +0100
1.3 @@ -0,0 +1,727 @@
1.4 +/* -*-mode:java; c-basic-offset:2; -*- */
1.5 +/*
1.6 +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
1.7 +
1.8 +Redistribution and use in source and binary forms, with or without
1.9 +modification, are permitted provided that the following conditions are met:
1.10 +
1.11 + 1. Redistributions of source code must retain the above copyright notice,
1.12 + this list of conditions and the following disclaimer.
1.13 +
1.14 + 2. Redistributions in binary form must reproduce the above copyright
1.15 + notice, this list of conditions and the following disclaimer in
1.16 + the documentation and/or other materials provided with the distribution.
1.17 +
1.18 + 3. The names of the authors may not be used to endorse or promote products
1.19 + derived from this software without specific prior written permission.
1.20 +
1.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
1.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
1.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
1.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
1.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
1.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.31 + */
1.32 +/*
1.33 + * This program is based on zlib-1.1.3, so all credit should go authors
1.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
1.35 + * and contributors of zlib.
1.36 + */
1.37 +
1.38 +package org.apidesign.bck2brwsr.emul.zip;
1.39 +
1.40 +import org.apidesign.bck2brwsr.emul.lang.System;
1.41 +
1.42 +final class Inflate{
1.43 +
1.44 + static final private int MAX_WBITS=15; // 32K LZ77 window
1.45 +
1.46 + // preset dictionary flag in zlib header
1.47 + static final private int PRESET_DICT=0x20;
1.48 +
1.49 + static final int Z_NO_FLUSH=0;
1.50 + static final int Z_PARTIAL_FLUSH=1;
1.51 + static final int Z_SYNC_FLUSH=2;
1.52 + static final int Z_FULL_FLUSH=3;
1.53 + static final int Z_FINISH=4;
1.54 +
1.55 + static final private int Z_DEFLATED=8;
1.56 +
1.57 + static final private int Z_OK=0;
1.58 + static final private int Z_STREAM_END=1;
1.59 + static final private int Z_NEED_DICT=2;
1.60 + static final private int Z_ERRNO=-1;
1.61 + static final private int Z_STREAM_ERROR=-2;
1.62 + static final private int Z_DATA_ERROR=-3;
1.63 + static final private int Z_MEM_ERROR=-4;
1.64 + static final private int Z_BUF_ERROR=-5;
1.65 + static final private int Z_VERSION_ERROR=-6;
1.66 +
1.67 + static final private int METHOD=0; // waiting for method byte
1.68 + static final private int FLAG=1; // waiting for flag byte
1.69 + static final private int DICT4=2; // four dictionary check bytes to go
1.70 + static final private int DICT3=3; // three dictionary check bytes to go
1.71 + static final private int DICT2=4; // two dictionary check bytes to go
1.72 + static final private int DICT1=5; // one dictionary check byte to go
1.73 + static final int DICT0=6; // waiting for inflateSetDictionary
1.74 + static final private int BLOCKS=7; // decompressing blocks
1.75 + static final private int CHECK4=8; // four check bytes to go
1.76 + static final private int CHECK3=9; // three check bytes to go
1.77 + static final private int CHECK2=10; // two check bytes to go
1.78 + static final private int CHECK1=11; // one check byte to go
1.79 + static final private int DONE=12; // finished check, done
1.80 + static final private int BAD=13; // got an error--stay here
1.81 +
1.82 + static final private int HEAD=14;
1.83 + static final private int LENGTH=15;
1.84 + static final private int TIME=16;
1.85 + static final private int OS=17;
1.86 + static final private int EXLEN=18;
1.87 + static final private int EXTRA=19;
1.88 + static final private int NAME=20;
1.89 + static final private int COMMENT=21;
1.90 + static final private int HCRC=22;
1.91 + static final private int FLAGS=23;
1.92 +
1.93 + int mode; // current inflate mode
1.94 +
1.95 + // mode dependent information
1.96 + int method; // if FLAGS, method byte
1.97 +
1.98 + // if CHECK, check values to compare
1.99 + long was = -1; // computed check value
1.100 + long need; // stream check value
1.101 +
1.102 + // if BAD, inflateSync's marker bytes count
1.103 + int marker;
1.104 +
1.105 + // mode independent information
1.106 + int wrap; // flag for no wrapper
1.107 + int wbits; // log2(window size) (8..15, defaults to 15)
1.108 +
1.109 + InfBlocks blocks; // current inflate_blocks state
1.110 +
1.111 + private final ZStream z;
1.112 +
1.113 + private int flags;
1.114 +
1.115 + private int need_bytes = -1;
1.116 + private byte[] crcbuf=new byte[4];
1.117 +
1.118 + GZIPHeader gheader = null;
1.119 +
1.120 + int inflateReset(){
1.121 + if(z == null) return Z_STREAM_ERROR;
1.122 +
1.123 + z.total_in = z.total_out = 0;
1.124 + z.msg = null;
1.125 + this.mode = HEAD;
1.126 + this.need_bytes = -1;
1.127 + this.blocks.reset();
1.128 + return Z_OK;
1.129 + }
1.130 +
1.131 + int inflateEnd(){
1.132 + if(blocks != null){
1.133 + blocks.free();
1.134 + }
1.135 + return Z_OK;
1.136 + }
1.137 +
1.138 + Inflate(ZStream z){
1.139 + this.z=z;
1.140 + }
1.141 +
1.142 + int inflateInit(int w){
1.143 + z.msg = null;
1.144 + blocks = null;
1.145 +
1.146 + // handle undocumented wrap option (no zlib header or check)
1.147 + wrap = 0;
1.148 + if(w < 0){
1.149 + w = - w;
1.150 + }
1.151 + else {
1.152 + wrap = (w >> 4) + 1;
1.153 + if(w < 48)
1.154 + w &= 15;
1.155 + }
1.156 +
1.157 + if(w<8 ||w>15){
1.158 + inflateEnd();
1.159 + return Z_STREAM_ERROR;
1.160 + }
1.161 + if(blocks != null && wbits != w){
1.162 + blocks.free();
1.163 + blocks=null;
1.164 + }
1.165 +
1.166 + // set window size
1.167 + wbits=w;
1.168 +
1.169 + this.blocks=new InfBlocks(z, 1<<w);
1.170 +
1.171 + // reset state
1.172 + inflateReset();
1.173 +
1.174 + return Z_OK;
1.175 + }
1.176 +
1.177 + int inflate(int f){
1.178 + int hold = 0;
1.179 +
1.180 + int r;
1.181 + int b;
1.182 +
1.183 + if(z == null || z.next_in == null){
1.184 + if(f == Z_FINISH && this.mode==HEAD)
1.185 + return Z_OK;
1.186 + return Z_STREAM_ERROR;
1.187 + }
1.188 +
1.189 + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
1.190 + r = Z_BUF_ERROR;
1.191 + while (true){
1.192 +
1.193 + switch (this.mode){
1.194 + case HEAD:
1.195 + if(wrap==0){
1.196 + this.mode = BLOCKS;
1.197 + break;
1.198 + }
1.199 +
1.200 + try { r=readBytes(2, r, f); }
1.201 + catch(Return e){ return e.r; }
1.202 +
1.203 + if((wrap&2)!=0 && this.need == 0x8b1fL) { // gzip header
1.204 + z.adler=new CRC32();
1.205 + checksum(2, this.need);
1.206 +
1.207 + if(gheader==null)
1.208 + gheader=new GZIPHeader();
1.209 +
1.210 + this.mode = FLAGS;
1.211 + break;
1.212 + }
1.213 +
1.214 + flags = 0;
1.215 +
1.216 + this.method = ((int)this.need)&0xff;
1.217 + b=((int)(this.need>>8))&0xff;
1.218 +
1.219 + if((wrap&1)==0 || // check if zlib header allowed
1.220 + (((this.method << 8)+b) % 31)!=0){
1.221 + this.mode = BAD;
1.222 + z.msg = "incorrect header check";
1.223 + // since zlib 1.2, it is allowted to inflateSync for this case.
1.224 + /*
1.225 + this.marker = 5; // can't try inflateSync
1.226 + */
1.227 + break;
1.228 + }
1.229 +
1.230 + if((this.method&0xf)!=Z_DEFLATED){
1.231 + this.mode = BAD;
1.232 + z.msg="unknown compression method";
1.233 + // since zlib 1.2, it is allowted to inflateSync for this case.
1.234 + /*
1.235 + this.marker = 5; // can't try inflateSync
1.236 + */
1.237 + break;
1.238 + }
1.239 +
1.240 + if((this.method>>4)+8>this.wbits){
1.241 + this.mode = BAD;
1.242 + z.msg="invalid window size";
1.243 + // since zlib 1.2, it is allowted to inflateSync for this case.
1.244 + /*
1.245 + this.marker = 5; // can't try inflateSync
1.246 + */
1.247 + break;
1.248 + }
1.249 +
1.250 + z.adler=new Adler32();
1.251 +
1.252 + if((b&PRESET_DICT)==0){
1.253 + this.mode = BLOCKS;
1.254 + break;
1.255 + }
1.256 + this.mode = DICT4;
1.257 + case DICT4:
1.258 +
1.259 + if(z.avail_in==0)return r;r=f;
1.260 +
1.261 + z.avail_in--; z.total_in++;
1.262 + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
1.263 + this.mode=DICT3;
1.264 + case DICT3:
1.265 +
1.266 + if(z.avail_in==0)return r;r=f;
1.267 +
1.268 + z.avail_in--; z.total_in++;
1.269 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
1.270 + this.mode=DICT2;
1.271 + case DICT2:
1.272 +
1.273 + if(z.avail_in==0)return r;r=f;
1.274 +
1.275 + z.avail_in--; z.total_in++;
1.276 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
1.277 + this.mode=DICT1;
1.278 + case DICT1:
1.279 +
1.280 + if(z.avail_in==0)return r;r=f;
1.281 +
1.282 + z.avail_in--; z.total_in++;
1.283 + this.need += (z.next_in[z.next_in_index++]&0xffL);
1.284 + z.adler.reset(this.need);
1.285 + this.mode = DICT0;
1.286 + return Z_NEED_DICT;
1.287 + case DICT0:
1.288 + this.mode = BAD;
1.289 + z.msg = "need dictionary";
1.290 + this.marker = 0; // can try inflateSync
1.291 + return Z_STREAM_ERROR;
1.292 + case BLOCKS:
1.293 + r = this.blocks.proc(r);
1.294 + if(r == Z_DATA_ERROR){
1.295 + this.mode = BAD;
1.296 + this.marker = 0; // can try inflateSync
1.297 + break;
1.298 + }
1.299 + if(r == Z_OK){
1.300 + r = f;
1.301 + }
1.302 + if(r != Z_STREAM_END){
1.303 + return r;
1.304 + }
1.305 + r = f;
1.306 + this.was=z.adler.getValue();
1.307 + this.blocks.reset();
1.308 + if(this.wrap==0){
1.309 + this.mode=DONE;
1.310 + break;
1.311 + }
1.312 + this.mode=CHECK4;
1.313 + case CHECK4:
1.314 +
1.315 + if(z.avail_in==0)return r;r=f;
1.316 +
1.317 + z.avail_in--; z.total_in++;
1.318 + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
1.319 + this.mode=CHECK3;
1.320 + case CHECK3:
1.321 +
1.322 + if(z.avail_in==0)return r;r=f;
1.323 +
1.324 + z.avail_in--; z.total_in++;
1.325 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
1.326 + this.mode = CHECK2;
1.327 + case CHECK2:
1.328 +
1.329 + if(z.avail_in==0)return r;r=f;
1.330 +
1.331 + z.avail_in--; z.total_in++;
1.332 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
1.333 + this.mode = CHECK1;
1.334 + case CHECK1:
1.335 +
1.336 + if(z.avail_in==0)return r;r=f;
1.337 +
1.338 + z.avail_in--; z.total_in++;
1.339 + this.need+=(z.next_in[z.next_in_index++]&0xffL);
1.340 +
1.341 + if(flags!=0){ // gzip
1.342 + this.need = ((this.need&0xff000000)>>24 |
1.343 + (this.need&0x00ff0000)>>8 |
1.344 + (this.need&0x0000ff00)<<8 |
1.345 + (this.need&0x0000ffff)<<24)&0xffffffffL;
1.346 + }
1.347 +
1.348 + if(((int)(this.was)) != ((int)(this.need))){
1.349 + z.msg = "incorrect data check";
1.350 + // chack is delayed
1.351 + /*
1.352 + this.mode = BAD;
1.353 + this.marker = 5; // can't try inflateSync
1.354 + break;
1.355 + */
1.356 + }
1.357 + else if(flags!=0 && gheader!=null){
1.358 + gheader.crc = this.need;
1.359 + }
1.360 +
1.361 + this.mode = LENGTH;
1.362 + case LENGTH:
1.363 + if (wrap!=0 && flags!=0) {
1.364 +
1.365 + try { r=readBytes(4, r, f); }
1.366 + catch(Return e){ return e.r; }
1.367 +
1.368 + if(z.msg!=null && z.msg.equals("incorrect data check")){
1.369 + this.mode = BAD;
1.370 + this.marker = 5; // can't try inflateSync
1.371 + break;
1.372 + }
1.373 +
1.374 + if (this.need != (z.total_out & 0xffffffffL)) {
1.375 + z.msg = "incorrect length check";
1.376 + this.mode = BAD;
1.377 + break;
1.378 + }
1.379 + z.msg = null;
1.380 + }
1.381 + else {
1.382 + if(z.msg!=null && z.msg.equals("incorrect data check")){
1.383 + this.mode = BAD;
1.384 + this.marker = 5; // can't try inflateSync
1.385 + break;
1.386 + }
1.387 + }
1.388 +
1.389 + this.mode = DONE;
1.390 + case DONE:
1.391 + return Z_STREAM_END;
1.392 + case BAD:
1.393 + return Z_DATA_ERROR;
1.394 +
1.395 + case FLAGS:
1.396 +
1.397 + try { r=readBytes(2, r, f); }
1.398 + catch(Return e){ return e.r; }
1.399 +
1.400 + flags = ((int)this.need)&0xffff;
1.401 +
1.402 + if ((flags & 0xff) != Z_DEFLATED) {
1.403 + z.msg = "unknown compression method";
1.404 + this.mode = BAD;
1.405 + break;
1.406 + }
1.407 + if ((flags & 0xe000)!=0) {
1.408 + z.msg = "unknown header flags set";
1.409 + this.mode = BAD;
1.410 + break;
1.411 + }
1.412 +
1.413 + if ((flags & 0x0200)!=0){
1.414 + checksum(2, this.need);
1.415 + }
1.416 +
1.417 + this.mode = TIME;
1.418 +
1.419 + case TIME:
1.420 + try { r=readBytes(4, r, f); }
1.421 + catch(Return e){ return e.r; }
1.422 + if(gheader!=null)
1.423 + gheader.time = this.need;
1.424 + if ((flags & 0x0200)!=0){
1.425 + checksum(4, this.need);
1.426 + }
1.427 + this.mode = OS;
1.428 + case OS:
1.429 + try { r=readBytes(2, r, f); }
1.430 + catch(Return e){ return e.r; }
1.431 + if(gheader!=null){
1.432 + gheader.xflags = ((int)this.need)&0xff;
1.433 + gheader.os = (((int)this.need)>>8)&0xff;
1.434 + }
1.435 + if ((flags & 0x0200)!=0){
1.436 + checksum(2, this.need);
1.437 + }
1.438 + this.mode = EXLEN;
1.439 + case EXLEN:
1.440 + if ((flags & 0x0400)!=0) {
1.441 + try { r=readBytes(2, r, f); }
1.442 + catch(Return e){ return e.r; }
1.443 + if(gheader!=null){
1.444 + gheader.extra = new byte[((int)this.need)&0xffff];
1.445 + }
1.446 + if ((flags & 0x0200)!=0){
1.447 + checksum(2, this.need);
1.448 + }
1.449 + }
1.450 + else if(gheader!=null){
1.451 + gheader.extra=null;
1.452 + }
1.453 + this.mode = EXTRA;
1.454 +
1.455 + case EXTRA:
1.456 + if ((flags & 0x0400)!=0) {
1.457 + try {
1.458 + r=readBytes(r, f);
1.459 + if(gheader!=null){
1.460 + byte[] foo = tmp_array;
1.461 + tmp_array=null;
1.462 + if(foo.length == gheader.extra.length){
1.463 + System.arraycopy(foo, 0, gheader.extra, 0, foo.length);
1.464 + }
1.465 + else{
1.466 + z.msg = "bad extra field length";
1.467 + this.mode = BAD;
1.468 + break;
1.469 + }
1.470 + }
1.471 + }
1.472 + catch(Return e){ return e.r; }
1.473 + }
1.474 + else if(gheader!=null){
1.475 + gheader.extra=null;
1.476 + }
1.477 + this.mode = NAME;
1.478 + case NAME:
1.479 + if ((flags & 0x0800)!=0) {
1.480 + try {
1.481 + r=readString(r, f);
1.482 + if(gheader!=null){
1.483 + gheader.name=tmp_array;
1.484 + }
1.485 + tmp_array=null;
1.486 + }
1.487 + catch(Return e){ return e.r; }
1.488 + }
1.489 + else if(gheader!=null){
1.490 + gheader.name=null;
1.491 + }
1.492 + this.mode = COMMENT;
1.493 + case COMMENT:
1.494 + if ((flags & 0x1000)!=0) {
1.495 + try {
1.496 + r=readString(r, f);
1.497 + if(gheader!=null){
1.498 + gheader.comment=tmp_array;
1.499 + }
1.500 + tmp_array=null;
1.501 + }
1.502 + catch(Return e){ return e.r; }
1.503 + }
1.504 + else if(gheader!=null){
1.505 + gheader.comment=null;
1.506 + }
1.507 + this.mode = HCRC;
1.508 + case HCRC:
1.509 + if ((flags & 0x0200)!=0) {
1.510 + try { r=readBytes(2, r, f); }
1.511 + catch(Return e){ return e.r; }
1.512 + if(gheader!=null){
1.513 + gheader.hcrc=(int)(this.need&0xffff);
1.514 + }
1.515 + if(this.need != (z.adler.getValue()&0xffffL)){
1.516 + this.mode = BAD;
1.517 + z.msg = "header crc mismatch";
1.518 + this.marker = 5; // can't try inflateSync
1.519 + break;
1.520 + }
1.521 + }
1.522 + z.adler = new CRC32();
1.523 +
1.524 + this.mode = BLOCKS;
1.525 + break;
1.526 + default:
1.527 + return Z_STREAM_ERROR;
1.528 + }
1.529 + }
1.530 + }
1.531 +
1.532 + int inflateSetDictionary(byte[] dictionary, int dictLength){
1.533 + if(z==null || (this.mode != DICT0 && this.wrap != 0)){
1.534 + return Z_STREAM_ERROR;
1.535 + }
1.536 +
1.537 + int index=0;
1.538 + int length = dictLength;
1.539 +
1.540 + if(this.mode==DICT0){
1.541 + long adler_need=z.adler.getValue();
1.542 + z.adler.reset();
1.543 + z.adler.update(dictionary, 0, dictLength);
1.544 + if(z.adler.getValue()!=adler_need){
1.545 + return Z_DATA_ERROR;
1.546 + }
1.547 + }
1.548 +
1.549 + z.adler.reset();
1.550 +
1.551 + if(length >= (1<<this.wbits)){
1.552 + length = (1<<this.wbits)-1;
1.553 + index=dictLength - length;
1.554 + }
1.555 + this.blocks.set_dictionary(dictionary, index, length);
1.556 + this.mode = BLOCKS;
1.557 + return Z_OK;
1.558 + }
1.559 +
1.560 + static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
1.561 +
1.562 + int inflateSync(){
1.563 + int n; // number of bytes to look at
1.564 + int p; // pointer to bytes
1.565 + int m; // number of marker bytes found in a row
1.566 + long r, w; // temporaries to save total_in and total_out
1.567 +
1.568 + // set up
1.569 + if(z == null)
1.570 + return Z_STREAM_ERROR;
1.571 + if(this.mode != BAD){
1.572 + this.mode = BAD;
1.573 + this.marker = 0;
1.574 + }
1.575 + if((n=z.avail_in)==0)
1.576 + return Z_BUF_ERROR;
1.577 +
1.578 + p=z.next_in_index;
1.579 + m=this.marker;
1.580 + // search
1.581 + while (n!=0 && m < 4){
1.582 + if(z.next_in[p] == mark[m]){
1.583 + m++;
1.584 + }
1.585 + else if(z.next_in[p]!=0){
1.586 + m = 0;
1.587 + }
1.588 + else{
1.589 + m = 4 - m;
1.590 + }
1.591 + p++; n--;
1.592 + }
1.593 +
1.594 + // restore
1.595 + z.total_in += p-z.next_in_index;
1.596 + z.next_in_index = p;
1.597 + z.avail_in = n;
1.598 + this.marker = m;
1.599 +
1.600 + // return no joy or set up to restart on a new block
1.601 + if(m != 4){
1.602 + return Z_DATA_ERROR;
1.603 + }
1.604 + r=z.total_in; w=z.total_out;
1.605 + inflateReset();
1.606 + z.total_in=r; z.total_out = w;
1.607 + this.mode = BLOCKS;
1.608 +
1.609 + return Z_OK;
1.610 + }
1.611 +
1.612 + // Returns true if inflate is currently at the end of a block generated
1.613 + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1.614 + // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
1.615 + // but removes the length bytes of the resulting empty stored block. When
1.616 + // decompressing, PPP checks that at the end of input packet, inflate is
1.617 + // waiting for these length bytes.
1.618 + int inflateSyncPoint(){
1.619 + if(z == null || this.blocks == null)
1.620 + return Z_STREAM_ERROR;
1.621 + return this.blocks.sync_point();
1.622 + }
1.623 +
1.624 + private int readBytes(int n, int r, int f) throws Return{
1.625 + if(need_bytes == -1){
1.626 + need_bytes=n;
1.627 + this.need=0;
1.628 + }
1.629 + while(need_bytes>0){
1.630 + if(z.avail_in==0){ throw new Return(r); }; r=f;
1.631 + z.avail_in--; z.total_in++;
1.632 + this.need = this.need |
1.633 + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8));
1.634 + need_bytes--;
1.635 + }
1.636 + if(n==2){
1.637 + this.need&=0xffffL;
1.638 + }
1.639 + else if(n==4) {
1.640 + this.need&=0xffffffffL;
1.641 + }
1.642 + need_bytes=-1;
1.643 + return r;
1.644 + }
1.645 + class Return extends Exception{
1.646 + int r;
1.647 + Return(int r){this.r=r; }
1.648 + }
1.649 +
1.650 + private byte[] tmp_array;
1.651 + private int readString(int r, int f) throws Return{
1.652 + int b=0;
1.653 + byte[] arr = new byte[4092];
1.654 + int at = 0;
1.655 + do {
1.656 + if(z.avail_in==0){ throw new Return(r); }; r=f;
1.657 + z.avail_in--; z.total_in++;
1.658 + b = z.next_in[z.next_in_index];
1.659 + if(b!=0) arr = append(arr, z.next_in[z.next_in_index], at++);
1.660 + z.adler.update(z.next_in, z.next_in_index, 1);
1.661 + z.next_in_index++;
1.662 + }while(b!=0);
1.663 +
1.664 + tmp_array = copy(arr, at);
1.665 +
1.666 + return r;
1.667 + }
1.668 +
1.669 + private int readBytes(int r, int f) throws Return{
1.670 + int b=0;
1.671 + byte[] arr = new byte[4092];
1.672 + int at = 0;
1.673 + while(this.need>0){
1.674 + if(z.avail_in==0){ throw new Return(r); }; r=f;
1.675 + z.avail_in--; z.total_in++;
1.676 + b = z.next_in[z.next_in_index];
1.677 + arr = append(arr, z.next_in[z.next_in_index], at++);
1.678 + z.adler.update(z.next_in, z.next_in_index, 1);
1.679 + z.next_in_index++;
1.680 + this.need--;
1.681 + }
1.682 +
1.683 + tmp_array = copy(arr, at);
1.684 +
1.685 + return r;
1.686 + }
1.687 +
1.688 + private static byte[] copy(byte[] arr, int len) {
1.689 + byte[] ret = new byte[len];
1.690 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, 0, ret, 0, len);
1.691 + return ret;
1.692 + }
1.693 + private static byte[] append(byte[] arr, byte b, int index) {
1.694 + arr[index] = b;
1.695 + return arr;
1.696 + }
1.697 +
1.698 + private void checksum(int n, long v){
1.699 + for(int i=0; i<n; i++){
1.700 + crcbuf[i]=(byte)(v&0xff);
1.701 + v>>=8;
1.702 + }
1.703 + z.adler.update(crcbuf, 0, n);
1.704 + }
1.705 +
1.706 + public GZIPHeader getGZIPHeader(){
1.707 + return gheader;
1.708 + }
1.709 +
1.710 + boolean inParsingHeader(){
1.711 + switch(mode){
1.712 + case HEAD:
1.713 + case DICT4:
1.714 + case DICT3:
1.715 + case DICT2:
1.716 + case DICT1:
1.717 + case FLAGS:
1.718 + case TIME:
1.719 + case OS:
1.720 + case EXLEN:
1.721 + case EXTRA:
1.722 + case NAME:
1.723 + case COMMENT:
1.724 + case HCRC:
1.725 + return true;
1.726 + default:
1.727 + return false;
1.728 + }
1.729 + }
1.730 +}