123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- using System;
- /*
- * $Id: Inflate.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $
- *
- Copyright (c) 2000,2001,2002,2003 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.
- */
- namespace Org.BouncyCastle.Utilities.Zlib {
- internal sealed class Inflate{
-
- private const int MAX_WBITS=15; // 32K LZ77 window
- // preset dictionary flag in zlib header
- private const int PRESET_DICT=0x20;
- internal const int Z_NO_FLUSH=0;
- internal const int Z_PARTIAL_FLUSH=1;
- internal const int Z_SYNC_FLUSH=2;
- internal const int Z_FULL_FLUSH=3;
- internal const int Z_FINISH=4;
- private const int Z_DEFLATED=8;
- private const int Z_OK=0;
- private const int Z_STREAM_END=1;
- private const int Z_NEED_DICT=2;
- private const int Z_ERRNO=-1;
- private const int Z_STREAM_ERROR=-2;
- private const int Z_DATA_ERROR=-3;
- private const int Z_MEM_ERROR=-4;
- private const int Z_BUF_ERROR=-5;
- private const int Z_VERSION_ERROR=-6;
- private const int METHOD=0; // waiting for method byte
- private const int FLAG=1; // waiting for flag byte
- private const int DICT4=2; // four dictionary check bytes to go
- private const int DICT3=3; // three dictionary check bytes to go
- private const int DICT2=4; // two dictionary check bytes to go
- private const int DICT1=5; // one dictionary check byte to go
- private const int DICT0=6; // waiting for inflateSetDictionary
- private const int BLOCKS=7; // decompressing blocks
- private const int CHECK4=8; // four check bytes to go
- private const int CHECK3=9; // three check bytes to go
- private const int CHECK2=10; // two check bytes to go
- private const int CHECK1=11; // one check byte to go
- private const int DONE=12; // finished check, done
- private const int BAD=13; // got an error--stay here
- internal int mode; // current inflate mode
- // mode dependent information
- internal int method; // if FLAGS, method byte
- // if CHECK, check values to compare
- internal long[] was=new long[1] ; // computed check value
- internal long need; // stream check value
- // if BAD, inflateSync's marker bytes count
- internal int marker;
- // mode independent information
- internal int nowrap; // flag for no wrapper
- internal int wbits; // log2(window size) (8..15, defaults to 15)
- internal InfBlocks blocks; // current inflate_blocks state
- internal int inflateReset(ZStream z){
- if(z == null || z.istate == null) return Z_STREAM_ERROR;
-
- z.total_in = z.total_out = 0;
- z.msg = null;
- z.istate.mode = z.istate.nowrap!=0 ? BLOCKS : METHOD;
- z.istate.blocks.reset(z, null);
- return Z_OK;
- }
- internal int inflateEnd(ZStream z){
- if(blocks != null)
- blocks.free(z);
- blocks=null;
- // ZFREE(z, z->state);
- return Z_OK;
- }
- internal int inflateInit(ZStream z, int w){
- z.msg = null;
- blocks = null;
- // handle undocumented nowrap option (no zlib header or check)
- nowrap = 0;
- if(w < 0){
- w = - w;
- nowrap = 1;
- }
- // set window size
- if(w<8 ||w>15){
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- wbits=w;
- z.istate.blocks=new InfBlocks(z,
- z.istate.nowrap!=0 ? null : this,
- 1<<w);
- // reset state
- inflateReset(z);
- return Z_OK;
- }
- internal int inflate(ZStream z, int f){
- int r;
- int b;
- if(z == null || z.istate == null || z.next_in == null)
- return Z_STREAM_ERROR;
- f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
- r = Z_BUF_ERROR;
- while (true){
- //System.out.println("mode: "+z.istate.mode);
- switch (z.istate.mode){
- case METHOD:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- if(((z.istate.method = z.next_in[z.next_in_index++])&0xf)!=Z_DEFLATED){
- z.istate.mode = BAD;
- z.msg="unknown compression method";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
- if((z.istate.method>>4)+8>z.istate.wbits){
- z.istate.mode = BAD;
- z.msg="invalid window size";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
- z.istate.mode=FLAG;
- goto case FLAG;
- case FLAG:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- b = (z.next_in[z.next_in_index++])&0xff;
- if((((z.istate.method << 8)+b) % 31)!=0){
- z.istate.mode = BAD;
- z.msg = "incorrect header check";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
- if((b&PRESET_DICT)==0){
- z.istate.mode = BLOCKS;
- break;
- }
- z.istate.mode = DICT4;
- goto case DICT4;
- case DICT4:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
- z.istate.mode=DICT3;
- goto case DICT3;
- case DICT3:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
- z.istate.mode=DICT2;
- goto case DICT2;
- case DICT2:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
- z.istate.mode=DICT1;
- goto case DICT1;
- case DICT1:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need += (z.next_in[z.next_in_index++]&0xffL);
- z.adler = z.istate.need;
- z.istate.mode = DICT0;
- return Z_NEED_DICT;
- case DICT0:
- z.istate.mode = BAD;
- z.msg = "need dictionary";
- z.istate.marker = 0; // can try inflateSync
- return Z_STREAM_ERROR;
- case BLOCKS:
- r = z.istate.blocks.proc(z, r);
- if(r == Z_DATA_ERROR){
- z.istate.mode = BAD;
- z.istate.marker = 0; // can try inflateSync
- break;
- }
- if(r == Z_OK){
- r = f;
- }
- if(r != Z_STREAM_END){
- return r;
- }
- r = f;
- z.istate.blocks.reset(z, z.istate.was);
- if(z.istate.nowrap!=0){
- z.istate.mode=DONE;
- break;
- }
- z.istate.mode=CHECK4;
- goto case CHECK4;
- case CHECK4:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
- z.istate.mode=CHECK3;
- goto case CHECK3;
- case CHECK3:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
- z.istate.mode = CHECK2;
- goto case CHECK2;
- case CHECK2:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
- z.istate.mode = CHECK1;
- goto case CHECK1;
- case CHECK1:
- if(z.avail_in==0)return r;r=f;
- z.avail_in--; z.total_in++;
- z.istate.need+=(z.next_in[z.next_in_index++]&0xffL);
- if(((int)(z.istate.was[0])) != ((int)(z.istate.need))){
- z.istate.mode = BAD;
- z.msg = "incorrect data check";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
- z.istate.mode = DONE;
- goto case DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
- }
- }
- internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength){
- int index=0;
- int length = dictLength;
- if(z==null || z.istate == null|| z.istate.mode != DICT0)
- return Z_STREAM_ERROR;
- if(z._adler.adler32(1L, dictionary, 0, dictLength)!=z.adler){
- return Z_DATA_ERROR;
- }
- z.adler = z._adler.adler32(0, null, 0, 0);
- if(length >= (1<<z.istate.wbits)){
- length = (1<<z.istate.wbits)-1;
- index=dictLength - length;
- }
- z.istate.blocks.set_dictionary(dictionary, index, length);
- z.istate.mode = BLOCKS;
- return Z_OK;
- }
- private static readonly byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
- internal int inflateSync(ZStream z){
- int n; // number of bytes to look at
- int p; // pointer to bytes
- int m; // number of marker bytes found in a row
- long r, w; // temporaries to save total_in and total_out
- // set up
- if(z == null || z.istate == null)
- return Z_STREAM_ERROR;
- if(z.istate.mode != BAD){
- z.istate.mode = BAD;
- z.istate.marker = 0;
- }
- if((n=z.avail_in)==0)
- return Z_BUF_ERROR;
- p=z.next_in_index;
- m=z.istate.marker;
- // search
- while (n!=0 && m < 4){
- if(z.next_in[p] == mark[m]){
- m++;
- }
- else if(z.next_in[p]!=0){
- m = 0;
- }
- else{
- m = 4 - m;
- }
- p++; n--;
- }
- // restore
- z.total_in += p-z.next_in_index;
- z.next_in_index = p;
- z.avail_in = n;
- z.istate.marker = m;
- // return no joy or set up to restart on a new block
- if(m != 4){
- return Z_DATA_ERROR;
- }
- r=z.total_in; w=z.total_out;
- inflateReset(z);
- z.total_in=r; z.total_out = w;
- z.istate.mode = BLOCKS;
- return Z_OK;
- }
- // Returns true if inflate is currently at the end of a block generated
- // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
- // but removes the length bytes of the resulting empty stored block. When
- // decompressing, PPP checks that at the end of input packet, inflate is
- // waiting for these length bytes.
- internal int inflateSyncPoint(ZStream z){
- if(z == null || z.istate == null || z.istate.blocks == null)
- return Z_STREAM_ERROR;
- return z.istate.blocks.sync_point();
- }
- }
- }
- #endif
|