rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 694 emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java@0d277415ed02
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
     1 /* -*-mode:java; c-basic-offset:2; -*- */
     2 /*
     3 Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
     4 
     5 Redistribution and use in source and binary forms, with or without
     6 modification, are permitted provided that the following conditions are met:
     7 
     8   1. Redistributions of source code must retain the above copyright notice,
     9      this list of conditions and the following disclaimer.
    10 
    11   2. Redistributions in binary form must reproduce the above copyright 
    12      notice, this list of conditions and the following disclaimer in 
    13      the documentation and/or other materials provided with the distribution.
    14 
    15   3. The names of the authors may not be used to endorse or promote products
    16      derived from this software without specific prior written permission.
    17 
    18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
    19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
    21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
    22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
    24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  */
    29 /*
    30  * This program is based on zlib-1.1.3, so all credit should go authors
    31  * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
    32  * and contributors of zlib.
    33  */
    34 
    35 package org.apidesign.bck2brwsr.emul.zip;
    36 
    37 import org.apidesign.bck2brwsr.emul.lang.System;
    38 
    39 final class InfBlocks{
    40   static final private int MANY=1440;
    41 
    42   // And'ing with mask[n] masks the lower n bits
    43   static final private int[] inflate_mask = {
    44     0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
    45     0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
    46     0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
    47     0x00007fff, 0x0000ffff
    48   };
    49 
    50   // Table for deflate from PKZIP's appnote.txt.
    51   static final int[] border = { // Order of the bit length code lengths
    52     16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
    53   };
    54 
    55   static final private int Z_OK=0;
    56   static final private int Z_STREAM_END=1;
    57   static final private int Z_NEED_DICT=2;
    58   static final private int Z_ERRNO=-1;
    59   static final private int Z_STREAM_ERROR=-2;
    60   static final private int Z_DATA_ERROR=-3;
    61   static final private int Z_MEM_ERROR=-4;
    62   static final private int Z_BUF_ERROR=-5;
    63   static final private int Z_VERSION_ERROR=-6;
    64 
    65   static final private int TYPE=0;  // get type bits (3, including end bit)
    66   static final private int LENS=1;  // get lengths for stored
    67   static final private int STORED=2;// processing stored block
    68   static final private int TABLE=3; // get table lengths
    69   static final private int BTREE=4; // get bit lengths tree for a dynamic block
    70   static final private int DTREE=5; // get length, distance trees for a dynamic block
    71   static final private int CODES=6; // processing fixed or dynamic block
    72   static final private int DRY=7;   // output remaining window bytes
    73   static final private int DONE=8;  // finished last block, done
    74   static final private int BAD=9;   // ot a data error--stuck here
    75 
    76   int mode;            // current inflate_block mode 
    77 
    78   int left;            // if STORED, bytes left to copy 
    79 
    80   int table;           // table lengths (14 bits) 
    81   int index;           // index into blens (or border) 
    82   int[] blens;         // bit lengths of codes 
    83   int[] bb=new int[1]; // bit length tree depth 
    84   int[] tb=new int[1]; // bit length decoding tree 
    85 
    86   int[] bl=new int[1];
    87   int[] bd=new int[1];
    88 
    89   int[][] tl=new int[1][];
    90   int[][] td=new int[1][];
    91   int[] tli=new int[1]; // tl_index
    92   int[] tdi=new int[1]; // td_index
    93 
    94   private final InfCodes codes;      // if CODES, current state 
    95 
    96   int last;            // true if this block is the last block 
    97 
    98   // mode independent information 
    99   int bitk;            // bits in bit buffer 
   100   int bitb;            // bit buffer 
   101   int[] hufts;         // single malloc for tree space 
   102   byte[] window;       // sliding window 
   103   int end;             // one byte after sliding window 
   104   int read;            // window read pointer 
   105   int write;           // window write pointer 
   106   private boolean check;
   107 
   108   private final InfTree inftree=new InfTree();
   109 
   110   private final ZStream z; 
   111 
   112   InfBlocks(ZStream z, int w){
   113     this.z=z;
   114     this.codes=new InfCodes(this.z, this);
   115     hufts=new int[MANY*3];
   116     window=new byte[w];
   117     end=w;
   118     this.check = (z.istate.wrap==0) ? false : true;
   119     mode = TYPE;
   120     reset();
   121   }
   122 
   123   void reset(){
   124     if(mode==BTREE || mode==DTREE){
   125     }
   126     if(mode==CODES){
   127       codes.free(z);
   128     }
   129     mode=TYPE;
   130     bitk=0;
   131     bitb=0;
   132     read=write=0;
   133     if(check){
   134       z.adler.reset();
   135     }
   136   }
   137 
   138   int proc(int r){
   139     int t;              // temporary storage
   140     int b;              // bit buffer
   141     int k;              // bits in bit buffer
   142     int p;              // input data pointer
   143     int n;              // bytes available there
   144     int q;              // output window write pointer
   145     int m;              // bytes to end of window or read pointer
   146 
   147     // copy input/output information to locals (UPDATE macro restores)
   148     {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;}
   149     {q=write;m=(int)(q<read?read-q-1:end-q);}
   150 
   151     // process input based on current state
   152     while(true){
   153       switch (mode){
   154       case TYPE:
   155 
   156 	while(k<(3)){
   157 	  if(n!=0){
   158 	    r=Z_OK;
   159 	  }
   160 	  else{
   161 	    bitb=b; bitk=k; 
   162 	    z.avail_in=n;
   163 	    z.total_in+=p-z.next_in_index;z.next_in_index=p;
   164 	    write=q;
   165 	    return inflate_flush(r);
   166 	  };
   167 	  n--;
   168 	  b|=(z.next_in[p++]&0xff)<<k;
   169 	  k+=8;
   170 	}
   171 	t = (int)(b & 7);
   172 	last = t & 1;
   173 
   174 	switch (t >>> 1){
   175         case 0:                         // stored 
   176           {b>>>=(3);k-=(3);}
   177           t = k & 7;                    // go to byte boundary
   178 
   179           {b>>>=(t);k-=(t);}
   180           mode = LENS;                  // get length of stored block
   181           break;
   182         case 1:                         // fixed
   183           InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
   184           codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
   185 
   186           {b>>>=(3);k-=(3);}
   187 
   188           mode = CODES;
   189           break;
   190         case 2:                         // dynamic
   191 
   192           {b>>>=(3);k-=(3);}
   193 
   194           mode = TABLE;
   195           break;
   196         case 3:                         // illegal
   197 
   198           {b>>>=(3);k-=(3);}
   199           mode = BAD;
   200           z.msg = "invalid block type";
   201           r = Z_DATA_ERROR;
   202 
   203 	  bitb=b; bitk=k; 
   204 	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   205 	  write=q;
   206 	  return inflate_flush(r);
   207 	}
   208 	break;
   209       case LENS:
   210 
   211 	while(k<(32)){
   212 	  if(n!=0){
   213 	    r=Z_OK;
   214 	  }
   215 	  else{
   216 	    bitb=b; bitk=k; 
   217 	    z.avail_in=n;
   218 	    z.total_in+=p-z.next_in_index;z.next_in_index=p;
   219 	    write=q;
   220 	    return inflate_flush(r);
   221 	  };
   222 	  n--;
   223 	  b|=(z.next_in[p++]&0xff)<<k;
   224 	  k+=8;
   225 	}
   226 
   227 	if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)){
   228 	  mode = BAD;
   229 	  z.msg = "invalid stored block lengths";
   230 	  r = Z_DATA_ERROR;
   231 
   232 	  bitb=b; bitk=k; 
   233 	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   234 	  write=q;
   235 	  return inflate_flush(r);
   236 	}
   237 	left = (b & 0xffff);
   238 	b = k = 0;                       // dump bits
   239 	mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE);
   240 	break;
   241       case STORED:
   242 	if (n == 0){
   243 	  bitb=b; bitk=k; 
   244 	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   245 	  write=q;
   246 	  return inflate_flush(r);
   247 	}
   248 
   249 	if(m==0){
   250 	  if(q==end&&read!=0){
   251 	    q=0; m=(int)(q<read?read-q-1:end-q);
   252 	  }
   253 	  if(m==0){
   254 	    write=q; 
   255 	    r=inflate_flush(r);
   256 	    q=write;m=(int)(q<read?read-q-1:end-q);
   257 	    if(q==end&&read!=0){
   258 	      q=0; m=(int)(q<read?read-q-1:end-q);
   259 	    }
   260 	    if(m==0){
   261 	      bitb=b; bitk=k; 
   262 	      z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   263 	      write=q;
   264 	      return inflate_flush(r);
   265 	    }
   266 	  }
   267 	}
   268 	r=Z_OK;
   269 
   270 	t = left;
   271 	if(t>n) t = n;
   272 	if(t>m) t = m;
   273 	System.arraycopy(z.next_in, p, window, q, t);
   274 	p += t;  n -= t;
   275 	q += t;  m -= t;
   276 	if ((left -= t) != 0)
   277 	  break;
   278 	mode = last!=0 ? DRY : TYPE;
   279 	break;
   280       case TABLE:
   281 
   282 	while(k<(14)){
   283 	  if(n!=0){
   284 	    r=Z_OK;
   285 	  }
   286 	  else{
   287 	    bitb=b; bitk=k; 
   288 	    z.avail_in=n;
   289 	    z.total_in+=p-z.next_in_index;z.next_in_index=p;
   290 	    write=q;
   291 	    return inflate_flush(r);
   292 	  };
   293 	  n--;
   294 	  b|=(z.next_in[p++]&0xff)<<k;
   295 	  k+=8;
   296 	}
   297 
   298 	table = t = (b & 0x3fff);
   299 	if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
   300 	  {
   301 	    mode = BAD;
   302 	    z.msg = "too many length or distance symbols";
   303 	    r = Z_DATA_ERROR;
   304 
   305 	    bitb=b; bitk=k; 
   306 	    z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   307 	    write=q;
   308 	    return inflate_flush(r);
   309 	  }
   310 	t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
   311 	if(blens==null || blens.length<t){
   312 	  blens=new int[t];
   313 	}
   314 	else{
   315 	  for(int i=0; i<t; i++){blens[i]=0;}
   316 	}
   317 
   318 	{b>>>=(14);k-=(14);}
   319 
   320 	index = 0;
   321 	mode = BTREE;
   322       case BTREE:
   323 	while (index < 4 + (table >>> 10)){
   324 	  while(k<(3)){
   325 	    if(n!=0){
   326 	      r=Z_OK;
   327 	    }
   328 	    else{
   329 	      bitb=b; bitk=k; 
   330 	      z.avail_in=n;
   331 	      z.total_in+=p-z.next_in_index;z.next_in_index=p;
   332 	      write=q;
   333 	      return inflate_flush(r);
   334 	    };
   335 	    n--;
   336 	    b|=(z.next_in[p++]&0xff)<<k;
   337 	    k+=8;
   338 	  }
   339 
   340 	  blens[border[index++]] = b&7;
   341 
   342 	  {b>>>=(3);k-=(3);}
   343 	}
   344 
   345 	while(index < 19){
   346 	  blens[border[index++]] = 0;
   347 	}
   348 
   349 	bb[0] = 7;
   350 	t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
   351 	if (t != Z_OK){
   352 	  r = t;
   353 	  if (r == Z_DATA_ERROR){
   354 	    blens=null;
   355 	    mode = BAD;
   356 	  }
   357 
   358 	  bitb=b; bitk=k; 
   359 	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   360 	  write=q;
   361 	  return inflate_flush(r);
   362 	}
   363 
   364 	index = 0;
   365 	mode = DTREE;
   366       case DTREE:
   367 	while (true){
   368 	  t = table;
   369 	  if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){
   370 	    break;
   371 	  }
   372 
   373 	  int[] h;
   374 	  int i, j, c;
   375 
   376 	  t = bb[0];
   377 
   378 	  while(k<(t)){
   379 	    if(n!=0){
   380 	      r=Z_OK;
   381 	    }
   382 	    else{
   383 	      bitb=b; bitk=k; 
   384 	      z.avail_in=n;
   385 	      z.total_in+=p-z.next_in_index;z.next_in_index=p;
   386 	      write=q;
   387 	      return inflate_flush(r);
   388 	    };
   389 	    n--;
   390 	    b|=(z.next_in[p++]&0xff)<<k;
   391 	    k+=8;
   392 	  }
   393 
   394 	  if(tb[0]==-1){
   395             //System.err.println("null...");
   396 	  }
   397 
   398 	  t=hufts[(tb[0]+(b&inflate_mask[t]))*3+1];
   399 	  c=hufts[(tb[0]+(b&inflate_mask[t]))*3+2];
   400 
   401 	  if (c < 16){
   402 	    b>>>=(t);k-=(t);
   403 	    blens[index++] = c;
   404 	  }
   405 	  else { // c == 16..18
   406 	    i = c == 18 ? 7 : c - 14;
   407 	    j = c == 18 ? 11 : 3;
   408 
   409 	    while(k<(t+i)){
   410 	      if(n!=0){
   411 		r=Z_OK;
   412 	      }
   413 	      else{
   414 		bitb=b; bitk=k; 
   415 		z.avail_in=n;
   416 		z.total_in+=p-z.next_in_index;z.next_in_index=p;
   417 		write=q;
   418 		return inflate_flush(r);
   419 	      };
   420 	      n--;
   421 	      b|=(z.next_in[p++]&0xff)<<k;
   422 	      k+=8;
   423 	    }
   424 
   425 	    b>>>=(t);k-=(t);
   426 
   427 	    j += (b & inflate_mask[i]);
   428 
   429 	    b>>>=(i);k-=(i);
   430 
   431 	    i = index;
   432 	    t = table;
   433 	    if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
   434 		(c == 16 && i < 1)){
   435 	      blens=null;
   436 	      mode = BAD;
   437 	      z.msg = "invalid bit length repeat";
   438 	      r = Z_DATA_ERROR;
   439 
   440 	      bitb=b; bitk=k; 
   441 	      z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   442 	      write=q;
   443 	      return inflate_flush(r);
   444 	    }
   445 
   446 	    c = c == 16 ? blens[i-1] : 0;
   447 	    do{
   448 	      blens[i++] = c;
   449 	    }
   450 	    while (--j!=0);
   451 	    index = i;
   452 	  }
   453 	}
   454 
   455 	tb[0]=-1;
   456 	{
   457 	  bl[0] = 9;         // must be <= 9 for lookahead assumptions
   458 	  bd[0] = 6;         // must be <= 9 for lookahead assumptions
   459 	  t = table;
   460 	  t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 
   461 					    1 + ((t >> 5) & 0x1f),
   462 					    blens, bl, bd, tli, tdi, hufts, z);
   463 
   464 	  if (t != Z_OK){
   465 	    if (t == Z_DATA_ERROR){
   466 	      blens=null;
   467 	      mode = BAD;
   468 	    }
   469 	    r = t;
   470 
   471 	    bitb=b; bitk=k; 
   472 	    z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   473 	    write=q;
   474 	    return inflate_flush(r);
   475 	  }
   476 	  codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]);
   477 	}
   478 	mode = CODES;
   479       case CODES:
   480 	bitb=b; bitk=k;
   481 	z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p;
   482 	write=q;
   483 
   484 	if ((r = codes.proc(r)) != Z_STREAM_END){
   485 	  return inflate_flush(r);
   486 	}
   487 	r = Z_OK;
   488 	codes.free(z);
   489 
   490 	p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk;
   491 	q=write;m=(int)(q<read?read-q-1:end-q);
   492 
   493 	if (last==0){
   494 	  mode = TYPE;
   495 	  break;
   496 	}
   497 	mode = DRY;
   498       case DRY:
   499 	write=q; 
   500 	r=inflate_flush(r); 
   501 	q=write; m=(int)(q<read?read-q-1:end-q);
   502 	if (read != write){
   503 	  bitb=b; bitk=k; 
   504 	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   505 	  write=q;
   506 	  return inflate_flush(r);
   507 	}
   508 	mode = DONE;
   509       case DONE:
   510 	r = Z_STREAM_END;
   511 
   512 	bitb=b; bitk=k; 
   513 	z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   514 	write=q;
   515 	return inflate_flush(r);
   516       case BAD:
   517 	r = Z_DATA_ERROR;
   518 
   519 	bitb=b; bitk=k; 
   520 	z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   521 	write=q;
   522 	return inflate_flush(r);
   523 
   524       default:
   525 	r = Z_STREAM_ERROR;
   526 
   527 	bitb=b; bitk=k; 
   528 	z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
   529 	write=q;
   530 	return inflate_flush(r);
   531       }
   532     }
   533   }
   534 
   535   void free(){
   536     reset();
   537     window=null;
   538     hufts=null;
   539     //ZFREE(z, s);
   540   }
   541 
   542   void set_dictionary(byte[] d, int start, int n){
   543     System.arraycopy(d, start, window, 0, n);
   544     read = write = n;
   545   }
   546 
   547   // Returns true if inflate is currently at the end of a block generated
   548   // by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
   549   int sync_point(){
   550     return mode == LENS ? 1 : 0;
   551   }
   552 
   553   // copy as much as possible from the sliding window to the output area
   554   int inflate_flush(int r){
   555     int n;
   556     int p;
   557     int q;
   558 
   559     // local copies of source and destination pointers
   560     p = z.next_out_index;
   561     q = read;
   562 
   563     // compute number of bytes to copy as far as end of window
   564     n = (int)((q <= write ? write : end) - q);
   565     if(n > z.avail_out) n = z.avail_out;
   566     if(n!=0 && r == Z_BUF_ERROR) r = Z_OK;
   567 
   568     // update counters
   569     z.avail_out -= n;
   570     z.total_out += n;
   571 
   572     // update check information
   573     if(check && n>0){
   574       z.adler.update(window, q, n);
   575     }
   576 
   577     // copy as far as end of window
   578     System.arraycopy(window, q, z.next_out, p, n);
   579     p += n;
   580     q += n;
   581 
   582     // see if more to copy at beginning of window
   583     if (q == end){
   584       // wrap pointers
   585       q = 0;
   586       if (write == end)
   587         write = 0;
   588 
   589       // compute bytes to copy
   590       n = write - q;
   591       if (n > z.avail_out) n = z.avail_out;
   592       if (n!=0 && r == Z_BUF_ERROR) r = Z_OK;
   593 
   594       // update counters
   595       z.avail_out -= n;
   596       z.total_out += n;
   597 
   598       // update check information
   599       if(check && n>0){
   600 	z.adler.update(window, q, n);
   601       }
   602 
   603       // copy
   604       System.arraycopy(window, q, z.next_out, p, n);
   605       p += n;
   606       q += n;
   607     }
   608 
   609     // update pointers
   610     z.next_out_index = p;
   611     read = q;
   612 
   613     // done
   614     return r;
   615   }
   616 }