Mes documents/Visual Studio 2005/Projects/TES4ModTranslator/TES4ModTranslator/Zip/Compression/Streams/InflaterInputStream.cs

Go to the documentation of this file.
00001 // InflaterInputStream.cs
00002 //
00003 // Copyright (C) 2001 Mike Krueger
00004 // Copyright (C) 2004 John Reilly
00005 //
00006 // This file was translated from java, it was part of the GNU Classpath
00007 // Copyright (C) 2001 Free Software Foundation, Inc.
00008 //
00009 // This program is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 //
00023 // Linking this library statically or dynamically with other modules is
00024 // making a combined work based on this library.  Thus, the terms and
00025 // conditions of the GNU General Public License cover the whole
00026 // combination.
00027 // 
00028 // As a special exception, the copyright holders of this library give you
00029 // permission to link this library with independent modules to produce an
00030 // executable, regardless of the license terms of these independent
00031 // modules, and to copy and distribute the resulting executable under
00032 // terms of your choice, provided that you also meet, for each linked
00033 // independent module, the terms and conditions of the license of that
00034 // module.  An independent module is a module which is not derived from
00035 // or based on this library.  If you modify this library, you may extend
00036 // this exception to your version of the library, but you are not
00037 // obligated to do so.  If you do not wish to do so, delete this
00038 // exception statement from your version.
00039 
00040 using System;
00041 using System.Security.Cryptography;
00042 using System.IO;
00043 
00044 using ICSharpCode.SharpZipLib.Zip.Compression;
00045 using ICSharpCode.SharpZipLib.Checksums;
00046 
00047 namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams 
00048 {
00049 
00056         public class InflaterInputBuffer
00057         {
00062                 public InflaterInputBuffer(Stream stream)
00063                 {
00064                         inputStream = stream;
00065                         rawData = new byte[4096];
00066                         clearText = rawData;
00067                 }
00068                 
00072                 public int RawLength
00073                 {
00074                         get { 
00075                                 return rawLength; 
00076                         }
00077                 }
00078                 
00083                 public byte[] RawData
00084                 {
00085                         get {
00086                                 return rawData;
00087                         }
00088                 }
00089                 
00093                 public int ClearTextLength
00094                 {
00095                         get {
00096                                 return clearTextLength;
00097                         }
00098                 }
00099                 
00103                 public byte[] ClearText
00104                 {
00105                         get {
00106                                 return clearText;
00107                         }
00108                 }
00109                 
00113                 public int Available
00114                 {
00115                         get { return available; }
00116                         set { available = value; }
00117                 }
00118 
00123                 public void SetInflaterInput(Inflater inflater)
00124                 {
00125                         if ( available > 0 ) {
00126                                 inflater.SetInput(clearText, clearTextLength - available, available);
00127                                 available = 0;
00128                         }
00129                 }
00130 
00134                 public void Fill()
00135                 {
00136                         rawLength = 0;
00137                         int toRead = rawData.Length;
00138                         
00139                         while (toRead > 0) {
00140                                 int count = inputStream.Read(rawData, rawLength, toRead);
00141                                 if ( count <= 0 ) {
00142                                         if (rawLength == 0) {
00143                                                 throw new SharpZipBaseException("Unexpected EOF"); 
00144                                         }
00145                                         break;
00146                                 }
00147                                 rawLength += count;
00148                                 toRead -= count;
00149                         }
00150 
00151                         if ( cryptoTransform != null ) {
00152                                 clearTextLength = cryptoTransform.TransformBlock(rawData, 0, rawLength, clearText, 0);
00153                         }
00154                         else {
00155                                 clearTextLength = rawLength;
00156                         }
00157 
00158                         available = clearTextLength;
00159                 }
00160                 
00166                 public int ReadRawBuffer(byte[] buffer)
00167                 {
00168                         return ReadRawBuffer(buffer, 0, buffer.Length);
00169                 }
00170 
00178                 public int ReadRawBuffer(byte[] outBuffer, int offset, int length)
00179                 {
00180                         if ( length <= 0 ) {
00181                                 throw new ArgumentOutOfRangeException("length");
00182                         }
00183                         
00184                         int currentOffset = offset;
00185                         int currentLength = length;
00186                         
00187                         while ( currentLength > 0 ) {
00188                                 if ( available <= 0 ) {
00189                                         Fill();
00190                                         if (available <= 0) {
00191                                                 return 0;
00192                                         }
00193                                 }
00194                                 int toCopy = Math.Min(currentLength, available);
00195                                 System.Array.Copy(rawData, rawLength - (int)available, outBuffer, currentOffset, toCopy);
00196             currentOffset += toCopy;
00197                                 currentLength -= toCopy;
00198                                 available -= toCopy;
00199                         }
00200                         return length;
00201                 }
00202                 
00210                 public int ReadClearTextBuffer(byte[] outBuffer, int offset, int length)
00211                 {
00212                         if ( length <= 0 ) {
00213                                 throw new ArgumentOutOfRangeException("length");
00214                         }
00215                         
00216                         int currentOffset = offset;
00217                         int currentLength = length;
00218                         
00219                         while ( currentLength > 0 ) {
00220                                 if ( available <= 0 ) {
00221                                         Fill();
00222                                         if (available <= 0) {
00223                                                 return 0;
00224                                         }
00225                                 }
00226                                 
00227                                 int toCopy = Math.Min(currentLength, available);
00228                                 System.Array.Copy(clearText, clearTextLength - (int)available, outBuffer, currentOffset, toCopy);
00229                                 currentOffset += toCopy;
00230                                 currentLength -= toCopy;
00231                                 available -= toCopy;
00232                         }
00233                         return length;
00234                 }
00235                 
00240                 public int ReadLeByte()
00241                 {
00242                         if (available <= 0) {
00243                                 Fill();
00244                                 if (available <= 0) {
00245                                         throw new ZipException("EOF in header");
00246                                 }
00247                         }
00248                         byte result = (byte)(rawData[rawLength - available] & 0xff);
00249                         available -= 1;
00250                         return result;
00251                 }
00252                 
00256                 public int ReadLeShort()
00257                 {
00258                         return ReadLeByte() | (ReadLeByte() << 8);
00259                 }
00260                 
00264                 public int ReadLeInt()
00265                 {
00266                         return ReadLeShort() | (ReadLeShort() << 16);
00267                 }
00268                 
00272                 public long ReadLeLong()
00273                 {
00274                         return ReadLeInt() | (ReadLeInt() << 32);
00275                 }
00276 
00281                 public ICryptoTransform CryptoTransform
00282                 {
00283                         set { 
00284                                 cryptoTransform = value;
00285                                 if ( cryptoTransform != null ) {
00286                                         if ( rawData == clearText ) {
00287                                                 if ( internalClearText == null ) {
00288                                                         internalClearText = new byte[4096];
00289                                                 }
00290                                                 clearText = internalClearText;
00291                                         }
00292                                         clearTextLength = rawLength;
00293                                         if ( available > 0 ) {
00294                                                 cryptoTransform.TransformBlock(rawData, rawLength - available, available, clearText, rawLength - available);
00295                                         }
00296                                 } else {
00297                                         clearText = rawData;
00298                                         clearTextLength = rawLength;
00299                                 }
00300                         }
00301                 }
00302 
00303                 #region Instance Fields
00304                 int rawLength;
00305                 byte[] rawData;
00306                 
00307                 int clearTextLength;
00308                 byte[] clearText;
00309                 
00310                 byte[] internalClearText;
00311                 
00312                 int available;
00313                 
00314                 ICryptoTransform cryptoTransform;
00315                 Stream inputStream;
00316                 #endregion
00317         }
00318         
00328         public class InflaterInputStream : Stream
00329         {
00333                 protected Inflater inf;
00334 
00338                 protected InflaterInputBuffer inputBuffer;
00339 
00343                 protected Stream baseInputStream;
00344                 
00348                 protected long csize;
00349 
00350                 bool isClosed = false;
00351                 bool isStreamOwner = true;
00352                 
00360                 public bool IsStreamOwner
00361                 {
00362                         get { return isStreamOwner; }
00363                         set { isStreamOwner = value; }
00364                 }
00365                 
00369                 public override bool CanRead {
00370                         get {
00371                                 return baseInputStream.CanRead;
00372                         }
00373                 }
00374                 
00378                 public override bool CanSeek {
00379                         get {
00380                                 return false;
00381                         }
00382                 }
00383                 
00387                 public override bool CanWrite {
00388                         get {
00389                                 return false;
00390                         }
00391                 }
00392                 
00396                 public override long Length {
00397                         get {
00398                                 return inputBuffer.RawLength;
00399                         }
00400                 }
00401                 
00407                 public override long Position {
00408                         get {
00409                                 return baseInputStream.Position;
00410                         }
00411                         set {
00412                                 throw new NotSupportedException("InflaterInputStream Position not supported");
00413                         }
00414                 }
00415                 
00419                 public override void Flush()
00420                 {
00421                         baseInputStream.Flush();
00422                 }
00423                 
00429                 public override long Seek(long offset, SeekOrigin origin)
00430                 {
00431                         throw new NotSupportedException("Seek not supported");
00432                 }
00433                 
00439                 public override void SetLength(long val)
00440                 {
00441                         throw new NotSupportedException("InflaterInputStream SetLength not supported");
00442                 }
00443                 
00449                 public override void Write(byte[] array, int offset, int count)
00450                 {
00451                         throw new NotSupportedException("InflaterInputStream Write not supported");
00452                 }
00453                 
00459                 public override void WriteByte(byte val)
00460                 {
00461                         throw new NotSupportedException("InflaterInputStream WriteByte not supported");
00462                 }
00463                 
00474                 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
00475                 {
00476                         throw new NotSupportedException("InflaterInputStream BeginWrite not supported");
00477                 }
00478                 
00486                 public InflaterInputStream(Stream baseInputStream) : this(baseInputStream, new Inflater(), 4096)
00487                 {
00488                 }
00489                 
00500                 public InflaterInputStream(Stream baseInputStream, Inflater inf) : this(baseInputStream, inf, 4096)
00501                 {
00502                 }
00503                 
00517                 public InflaterInputStream(Stream baseInputStream, Inflater inflater, int bufferSize)
00518                 {
00519                         if (baseInputStream == null) {
00520                                 throw new ArgumentNullException("InflaterInputStream baseInputStream is null");
00521                         }
00522                         
00523                         if (inflater == null) {
00524                                 throw new ArgumentNullException("InflaterInputStream Inflater is null");
00525                         }
00526                         
00527                         if (bufferSize <= 0) {
00528                                 throw new ArgumentOutOfRangeException("bufferSize");
00529                         }
00530                         
00531                         this.baseInputStream = baseInputStream;
00532                         this.inf = inflater;
00533                         
00534                         inputBuffer = new InflaterInputBuffer(baseInputStream);
00535                 }
00536                 
00541                 public virtual int Available {
00542                         get {
00543                                 return inf.IsFinished ? 0 : 1;
00544                         }
00545                 }
00546                 
00551                 public override void Close()
00552                 {
00553                         if ( !isClosed ) {
00554                                 isClosed = true;
00555                                 if ( isStreamOwner ) {
00556                                         baseInputStream.Close();
00557                                 }
00558                         }
00559                 }
00560 
00567                 protected void Fill()
00568                 {
00569                         inputBuffer.Fill();
00570                         inputBuffer.SetInflaterInput(inf);
00571                 }
00572 
00589                 public override int Read(byte[] b, int off, int len)
00590                 {
00591                         for (;;) {
00592                                 int count;
00593                                 try {
00594                                         count = inf.Inflate(b, off, len);
00595                                 } catch (Exception e) {
00596                                         throw new SharpZipBaseException(e.ToString());
00597                                 }
00598                                 
00599                                 if (count > 0) {
00600                                         return count;
00601                                 }
00602                                 
00603                                 if (inf.IsNeedingDictionary) {
00604                                         throw new SharpZipBaseException("Need a dictionary");
00605                                 } else if (inf.IsFinished) {
00606                                         return 0;
00607                                 } else if (inf.IsNeedingInput) {
00608                                         Fill();
00609                                 } else {
00610                                         throw new InvalidOperationException("Don't know what to do");
00611                                 }
00612                         }
00613                 }
00614                 
00628                 public long Skip(long n)
00629                 {
00630                         if (n <= 0) {
00631                                 throw new ArgumentOutOfRangeException("n");
00632                         }
00633                         
00634                         // v0.80 Skip by seeking if underlying stream supports it...
00635                         if (baseInputStream.CanSeek) {
00636                                 baseInputStream.Seek(n, SeekOrigin.Current);
00637                                 return n;
00638                         } else {
00639                                 int len = 2048;
00640                                 if (n < len) {
00641                                         len = (int) n;
00642                                 }
00643                                 byte[] tmp = new byte[len];
00644                                 return (long)baseInputStream.Read(tmp, 0, tmp.Length);
00645                         }
00646                 }
00647                 
00651                 protected void StopDecrypting()
00652                 {
00653                         inputBuffer.CryptoTransform = null;
00654                 }
00655         }
00656 }

Generated on Fri Jun 23 21:50:05 2006 for OblivionModTranslator by  doxygen 1.4.6-NO