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/InfCodes.java Thu Feb 07 12:58:12 2013 +0100
1.3 @@ -0,0 +1,612 @@
1.4 +/* -*-mode:java; c-basic-offset:2; -*- */
1.5 +/*
1.6 +Copyright (c) 2000,2001,2002,2003 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 InfCodes{
1.43 +
1.44 + static final private int[] inflate_mask = {
1.45 + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
1.46 + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
1.47 + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
1.48 + 0x00007fff, 0x0000ffff
1.49 + };
1.50 +
1.51 + static final private int Z_OK=0;
1.52 + static final private int Z_STREAM_END=1;
1.53 + static final private int Z_NEED_DICT=2;
1.54 + static final private int Z_ERRNO=-1;
1.55 + static final private int Z_STREAM_ERROR=-2;
1.56 + static final private int Z_DATA_ERROR=-3;
1.57 + static final private int Z_MEM_ERROR=-4;
1.58 + static final private int Z_BUF_ERROR=-5;
1.59 + static final private int Z_VERSION_ERROR=-6;
1.60 +
1.61 + // waiting for "i:"=input,
1.62 + // "o:"=output,
1.63 + // "x:"=nothing
1.64 + static final private int START=0; // x: set up for LEN
1.65 + static final private int LEN=1; // i: get length/literal/eob next
1.66 + static final private int LENEXT=2; // i: getting length extra (have base)
1.67 + static final private int DIST=3; // i: get distance next
1.68 + static final private int DISTEXT=4;// i: getting distance extra
1.69 + static final private int COPY=5; // o: copying bytes in window, waiting for space
1.70 + static final private int LIT=6; // o: got literal, waiting for output space
1.71 + static final private int WASH=7; // o: got eob, possibly still output waiting
1.72 + static final private int END=8; // x: got eob and all data flushed
1.73 + static final private int BADCODE=9;// x: got error
1.74 +
1.75 + int mode; // current inflate_codes mode
1.76 +
1.77 + // mode dependent information
1.78 + int len;
1.79 +
1.80 + int[] tree; // pointer into tree
1.81 + int tree_index=0;
1.82 + int need; // bits needed
1.83 +
1.84 + int lit;
1.85 +
1.86 + // if EXT or COPY, where and how much
1.87 + int get; // bits to get for extra
1.88 + int dist; // distance back to copy from
1.89 +
1.90 + byte lbits; // ltree bits decoded per branch
1.91 + byte dbits; // dtree bits decoder per branch
1.92 + int[] ltree; // literal/length/eob tree
1.93 + int ltree_index; // literal/length/eob tree
1.94 + int[] dtree; // distance tree
1.95 + int dtree_index; // distance tree
1.96 +
1.97 + private final ZStream z;
1.98 + private final InfBlocks s;
1.99 + InfCodes(ZStream z, InfBlocks s){
1.100 + this.z=z;
1.101 + this.s=s;
1.102 + }
1.103 +
1.104 + void init(int bl, int bd,
1.105 + int[] tl, int tl_index,
1.106 + int[] td, int td_index){
1.107 + mode=START;
1.108 + lbits=(byte)bl;
1.109 + dbits=(byte)bd;
1.110 + ltree=tl;
1.111 + ltree_index=tl_index;
1.112 + dtree = td;
1.113 + dtree_index=td_index;
1.114 + tree=null;
1.115 + }
1.116 +
1.117 + int proc(int r){
1.118 + int j; // temporary storage
1.119 + int[] t; // temporary pointer
1.120 + int tindex; // temporary pointer
1.121 + int e; // extra bits or operation
1.122 + int b=0; // bit buffer
1.123 + int k=0; // bits in bit buffer
1.124 + int p=0; // input data pointer
1.125 + int n; // bytes available there
1.126 + int q; // output window write pointer
1.127 + int m; // bytes to end of window or read pointer
1.128 + int f; // pointer to copy strings from
1.129 +
1.130 + // copy input/output information to locals (UPDATE macro restores)
1.131 + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
1.132 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
1.133 +
1.134 + // process input and output based on current state
1.135 + while (true){
1.136 + switch (mode){
1.137 + // waiting for "i:"=input, "o:"=output, "x:"=nothing
1.138 + case START: // x: set up for LEN
1.139 + if (m >= 258 && n >= 10){
1.140 +
1.141 + s.bitb=b;s.bitk=k;
1.142 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.143 + s.write=q;
1.144 + r = inflate_fast(lbits, dbits,
1.145 + ltree, ltree_index,
1.146 + dtree, dtree_index,
1.147 + s, z);
1.148 +
1.149 + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
1.150 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
1.151 +
1.152 + if (r != Z_OK){
1.153 + mode = r == Z_STREAM_END ? WASH : BADCODE;
1.154 + break;
1.155 + }
1.156 + }
1.157 + need = lbits;
1.158 + tree = ltree;
1.159 + tree_index=ltree_index;
1.160 +
1.161 + mode = LEN;
1.162 + case LEN: // i: get length/literal/eob next
1.163 + j = need;
1.164 +
1.165 + while(k<(j)){
1.166 + if(n!=0)r=Z_OK;
1.167 + else{
1.168 +
1.169 + s.bitb=b;s.bitk=k;
1.170 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.171 + s.write=q;
1.172 + return s.inflate_flush(r);
1.173 + }
1.174 + n--;
1.175 + b|=(z.next_in[p++]&0xff)<<k;
1.176 + k+=8;
1.177 + }
1.178 +
1.179 + tindex=(tree_index+(b&inflate_mask[j]))*3;
1.180 +
1.181 + b>>>=(tree[tindex+1]);
1.182 + k-=(tree[tindex+1]);
1.183 +
1.184 + e=tree[tindex];
1.185 +
1.186 + if(e == 0){ // literal
1.187 + lit = tree[tindex+2];
1.188 + mode = LIT;
1.189 + break;
1.190 + }
1.191 + if((e & 16)!=0 ){ // length
1.192 + get = e & 15;
1.193 + len = tree[tindex+2];
1.194 + mode = LENEXT;
1.195 + break;
1.196 + }
1.197 + if ((e & 64) == 0){ // next table
1.198 + need = e;
1.199 + tree_index = tindex/3+tree[tindex+2];
1.200 + break;
1.201 + }
1.202 + if ((e & 32)!=0){ // end of block
1.203 + mode = WASH;
1.204 + break;
1.205 + }
1.206 + mode = BADCODE; // invalid code
1.207 + z.msg = "invalid literal/length code";
1.208 + r = Z_DATA_ERROR;
1.209 +
1.210 + s.bitb=b;s.bitk=k;
1.211 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.212 + s.write=q;
1.213 + return s.inflate_flush(r);
1.214 +
1.215 + case LENEXT: // i: getting length extra (have base)
1.216 + j = get;
1.217 +
1.218 + while(k<(j)){
1.219 + if(n!=0)r=Z_OK;
1.220 + else{
1.221 +
1.222 + s.bitb=b;s.bitk=k;
1.223 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.224 + s.write=q;
1.225 + return s.inflate_flush(r);
1.226 + }
1.227 + n--; b|=(z.next_in[p++]&0xff)<<k;
1.228 + k+=8;
1.229 + }
1.230 +
1.231 + len += (b & inflate_mask[j]);
1.232 +
1.233 + b>>=j;
1.234 + k-=j;
1.235 +
1.236 + need = dbits;
1.237 + tree = dtree;
1.238 + tree_index=dtree_index;
1.239 + mode = DIST;
1.240 + case DIST: // i: get distance next
1.241 + j = need;
1.242 +
1.243 + while(k<(j)){
1.244 + if(n!=0)r=Z_OK;
1.245 + else{
1.246 +
1.247 + s.bitb=b;s.bitk=k;
1.248 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.249 + s.write=q;
1.250 + return s.inflate_flush(r);
1.251 + }
1.252 + n--; b|=(z.next_in[p++]&0xff)<<k;
1.253 + k+=8;
1.254 + }
1.255 +
1.256 + tindex=(tree_index+(b & inflate_mask[j]))*3;
1.257 +
1.258 + b>>=tree[tindex+1];
1.259 + k-=tree[tindex+1];
1.260 +
1.261 + e = (tree[tindex]);
1.262 + if((e & 16)!=0){ // distance
1.263 + get = e & 15;
1.264 + dist = tree[tindex+2];
1.265 + mode = DISTEXT;
1.266 + break;
1.267 + }
1.268 + if ((e & 64) == 0){ // next table
1.269 + need = e;
1.270 + tree_index = tindex/3 + tree[tindex+2];
1.271 + break;
1.272 + }
1.273 + mode = BADCODE; // invalid code
1.274 + z.msg = "invalid distance code";
1.275 + r = Z_DATA_ERROR;
1.276 +
1.277 + s.bitb=b;s.bitk=k;
1.278 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.279 + s.write=q;
1.280 + return s.inflate_flush(r);
1.281 +
1.282 + case DISTEXT: // i: getting distance extra
1.283 + j = get;
1.284 +
1.285 + while(k<(j)){
1.286 + if(n!=0)r=Z_OK;
1.287 + else{
1.288 +
1.289 + s.bitb=b;s.bitk=k;
1.290 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.291 + s.write=q;
1.292 + return s.inflate_flush(r);
1.293 + }
1.294 + n--; b|=(z.next_in[p++]&0xff)<<k;
1.295 + k+=8;
1.296 + }
1.297 +
1.298 + dist += (b & inflate_mask[j]);
1.299 +
1.300 + b>>=j;
1.301 + k-=j;
1.302 +
1.303 + mode = COPY;
1.304 + case COPY: // o: copying bytes in window, waiting for space
1.305 + f = q - dist;
1.306 + while(f < 0){ // modulo window size-"while" instead
1.307 + f += s.end; // of "if" handles invalid distances
1.308 + }
1.309 + while (len!=0){
1.310 +
1.311 + if(m==0){
1.312 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
1.313 + if(m==0){
1.314 + s.write=q; r=s.inflate_flush(r);
1.315 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
1.316 +
1.317 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
1.318 +
1.319 + if(m==0){
1.320 + s.bitb=b;s.bitk=k;
1.321 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.322 + s.write=q;
1.323 + return s.inflate_flush(r);
1.324 + }
1.325 + }
1.326 + }
1.327 +
1.328 + s.window[q++]=s.window[f++]; m--;
1.329 +
1.330 + if (f == s.end)
1.331 + f = 0;
1.332 + len--;
1.333 + }
1.334 + mode = START;
1.335 + break;
1.336 + case LIT: // o: got literal, waiting for output space
1.337 + if(m==0){
1.338 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
1.339 + if(m==0){
1.340 + s.write=q; r=s.inflate_flush(r);
1.341 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
1.342 +
1.343 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
1.344 + if(m==0){
1.345 + s.bitb=b;s.bitk=k;
1.346 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.347 + s.write=q;
1.348 + return s.inflate_flush(r);
1.349 + }
1.350 + }
1.351 + }
1.352 + r=Z_OK;
1.353 +
1.354 + s.window[q++]=(byte)lit; m--;
1.355 +
1.356 + mode = START;
1.357 + break;
1.358 + case WASH: // o: got eob, possibly more output
1.359 + if (k > 7){ // return unused byte, if any
1.360 + k -= 8;
1.361 + n++;
1.362 + p--; // can always return one
1.363 + }
1.364 +
1.365 + s.write=q; r=s.inflate_flush(r);
1.366 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
1.367 +
1.368 + if (s.read != s.write){
1.369 + s.bitb=b;s.bitk=k;
1.370 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.371 + s.write=q;
1.372 + return s.inflate_flush(r);
1.373 + }
1.374 + mode = END;
1.375 + case END:
1.376 + r = Z_STREAM_END;
1.377 + s.bitb=b;s.bitk=k;
1.378 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.379 + s.write=q;
1.380 + return s.inflate_flush(r);
1.381 +
1.382 + case BADCODE: // x: got error
1.383 +
1.384 + r = Z_DATA_ERROR;
1.385 +
1.386 + s.bitb=b;s.bitk=k;
1.387 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.388 + s.write=q;
1.389 + return s.inflate_flush(r);
1.390 +
1.391 + default:
1.392 + r = Z_STREAM_ERROR;
1.393 +
1.394 + s.bitb=b;s.bitk=k;
1.395 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.396 + s.write=q;
1.397 + return s.inflate_flush(r);
1.398 + }
1.399 + }
1.400 + }
1.401 +
1.402 + void free(ZStream z){
1.403 + // ZFREE(z, c);
1.404 + }
1.405 +
1.406 + // Called with number of bytes left to write in window at least 258
1.407 + // (the maximum string length) and number of input bytes available
1.408 + // at least ten. The ten bytes are six bytes for the longest length/
1.409 + // distance pair plus four bytes for overloading the bit buffer.
1.410 +
1.411 + int inflate_fast(int bl, int bd,
1.412 + int[] tl, int tl_index,
1.413 + int[] td, int td_index,
1.414 + InfBlocks s, ZStream z){
1.415 + int t; // temporary pointer
1.416 + int[] tp; // temporary pointer
1.417 + int tp_index; // temporary pointer
1.418 + int e; // extra bits or operation
1.419 + int b; // bit buffer
1.420 + int k; // bits in bit buffer
1.421 + int p; // input data pointer
1.422 + int n; // bytes available there
1.423 + int q; // output window write pointer
1.424 + int m; // bytes to end of window or read pointer
1.425 + int ml; // mask for literal/length tree
1.426 + int md; // mask for distance tree
1.427 + int c; // bytes to copy
1.428 + int d; // distance back to copy from
1.429 + int r; // copy source pointer
1.430 +
1.431 + int tp_index_t_3; // (tp_index+t)*3
1.432 +
1.433 + // load input, output, bit values
1.434 + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
1.435 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
1.436 +
1.437 + // initialize masks
1.438 + ml = inflate_mask[bl];
1.439 + md = inflate_mask[bd];
1.440 +
1.441 + // do until not enough input or output space for fast loop
1.442 + do { // assume called with m >= 258 && n >= 10
1.443 + // get literal/length code
1.444 + while(k<(20)){ // max bits for literal/length code
1.445 + n--;
1.446 + b|=(z.next_in[p++]&0xff)<<k;k+=8;
1.447 + }
1.448 +
1.449 + t= b&ml;
1.450 + tp=tl;
1.451 + tp_index=tl_index;
1.452 + tp_index_t_3=(tp_index+t)*3;
1.453 + if ((e = tp[tp_index_t_3]) == 0){
1.454 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
1.455 +
1.456 + s.window[q++] = (byte)tp[tp_index_t_3+2];
1.457 + m--;
1.458 + continue;
1.459 + }
1.460 + do {
1.461 +
1.462 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
1.463 +
1.464 + if((e&16)!=0){
1.465 + e &= 15;
1.466 + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]);
1.467 +
1.468 + b>>=e; k-=e;
1.469 +
1.470 + // decode distance base of block to copy
1.471 + while(k<(15)){ // max bits for distance code
1.472 + n--;
1.473 + b|=(z.next_in[p++]&0xff)<<k;k+=8;
1.474 + }
1.475 +
1.476 + t= b&md;
1.477 + tp=td;
1.478 + tp_index=td_index;
1.479 + tp_index_t_3=(tp_index+t)*3;
1.480 + e = tp[tp_index_t_3];
1.481 +
1.482 + do {
1.483 +
1.484 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
1.485 +
1.486 + if((e&16)!=0){
1.487 + // get extra bits to add to distance base
1.488 + e &= 15;
1.489 + while(k<(e)){ // get extra bits (up to 13)
1.490 + n--;
1.491 + b|=(z.next_in[p++]&0xff)<<k;k+=8;
1.492 + }
1.493 +
1.494 + d = tp[tp_index_t_3+2] + (b&inflate_mask[e]);
1.495 +
1.496 + b>>=(e); k-=(e);
1.497 +
1.498 + // do the copy
1.499 + m -= c;
1.500 + if (q >= d){ // offset before dest
1.501 + // just copy
1.502 + r=q-d;
1.503 + if(q-r>0 && 2>(q-r)){
1.504 + s.window[q++]=s.window[r++]; // minimum count is three,
1.505 + s.window[q++]=s.window[r++]; // so unroll loop a little
1.506 + c-=2;
1.507 + }
1.508 + else{
1.509 + System.arraycopy(s.window, r, s.window, q, 2);
1.510 + q+=2; r+=2; c-=2;
1.511 + }
1.512 + }
1.513 + else{ // else offset after destination
1.514 + r=q-d;
1.515 + do{
1.516 + r+=s.end; // force pointer in window
1.517 + }while(r<0); // covers invalid distances
1.518 + e=s.end-r;
1.519 + if(c>e){ // if source crosses,
1.520 + c-=e; // wrapped copy
1.521 + if(q-r>0 && e>(q-r)){
1.522 + do{s.window[q++] = s.window[r++];}
1.523 + while(--e!=0);
1.524 + }
1.525 + else{
1.526 + System.arraycopy(s.window, r, s.window, q, e);
1.527 + q+=e; r+=e; e=0;
1.528 + }
1.529 + r = 0; // copy rest from start of window
1.530 + }
1.531 +
1.532 + }
1.533 +
1.534 + // copy all or what's left
1.535 + if(q-r>0 && c>(q-r)){
1.536 + do{s.window[q++] = s.window[r++];}
1.537 + while(--c!=0);
1.538 + }
1.539 + else{
1.540 + System.arraycopy(s.window, r, s.window, q, c);
1.541 + q+=c; r+=c; c=0;
1.542 + }
1.543 + break;
1.544 + }
1.545 + else if((e&64)==0){
1.546 + t+=tp[tp_index_t_3+2];
1.547 + t+=(b&inflate_mask[e]);
1.548 + tp_index_t_3=(tp_index+t)*3;
1.549 + e=tp[tp_index_t_3];
1.550 + }
1.551 + else{
1.552 + z.msg = "invalid distance code";
1.553 +
1.554 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
1.555 +
1.556 + s.bitb=b;s.bitk=k;
1.557 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.558 + s.write=q;
1.559 +
1.560 + return Z_DATA_ERROR;
1.561 + }
1.562 + }
1.563 + while(true);
1.564 + break;
1.565 + }
1.566 +
1.567 + if((e&64)==0){
1.568 + t+=tp[tp_index_t_3+2];
1.569 + t+=(b&inflate_mask[e]);
1.570 + tp_index_t_3=(tp_index+t)*3;
1.571 + if((e=tp[tp_index_t_3])==0){
1.572 +
1.573 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
1.574 +
1.575 + s.window[q++]=(byte)tp[tp_index_t_3+2];
1.576 + m--;
1.577 + break;
1.578 + }
1.579 + }
1.580 + else if((e&32)!=0){
1.581 +
1.582 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
1.583 +
1.584 + s.bitb=b;s.bitk=k;
1.585 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.586 + s.write=q;
1.587 +
1.588 + return Z_STREAM_END;
1.589 + }
1.590 + else{
1.591 + z.msg="invalid literal/length code";
1.592 +
1.593 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
1.594 +
1.595 + s.bitb=b;s.bitk=k;
1.596 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.597 + s.write=q;
1.598 +
1.599 + return Z_DATA_ERROR;
1.600 + }
1.601 + }
1.602 + while(true);
1.603 + }
1.604 + while(m>=258 && n>= 10);
1.605 +
1.606 + // not enough input or output--restore pointers and return
1.607 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
1.608 +
1.609 + s.bitb=b;s.bitk=k;
1.610 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
1.611 + s.write=q;
1.612 +
1.613 + return Z_OK;
1.614 + }
1.615 +}