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

Go to the documentation of this file.
00001 // DeflaterOutputStream.cs
00002 //
00003 // Copyright (C) 2001 Mike Krueger
00004 //
00005 // This file was translated from java, it was part of the GNU Classpath
00006 // Copyright (C) 2001 Free Software Foundation, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00021 //
00022 // Linking this library statically or dynamically with other modules is
00023 // making a combined work based on this library.  Thus, the terms and
00024 // conditions of the GNU General Public License cover the whole
00025 // combination.
00026 // 
00027 // As a special exception, the copyright holders of this library give you
00028 // permission to link this library with independent modules to produce an
00029 // executable, regardless of the license terms of these independent
00030 // modules, and to copy and distribute the resulting executable under
00031 // terms of your choice, provided that you also meet, for each linked
00032 // independent module, the terms and conditions of the license of that
00033 // module.  An independent module is a module which is not derived from
00034 // or based on this library.  If you modify this library, you may extend
00035 // this exception to your version of the library, but you are not
00036 // obligated to do so.  If you do not wish to do so, delete this
00037 // exception statement from your version.
00038 
00039 using System;
00040 using System.IO;
00041 using ICSharpCode.SharpZipLib.Checksums;
00042 using ICSharpCode.SharpZipLib.Zip.Compression;
00043 
00044 namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams 
00045 {
00046 
00052         public class DeflaterOutputStream : Stream
00053         {
00058                 protected byte[] buf;
00059                 
00063                 protected Deflater def;
00064                 
00068                 protected Stream baseOutputStream;
00069 
00070                 bool isClosed = false;
00071                 bool isStreamOwner = true;
00072                 
00077                 public bool IsStreamOwner
00078                 {
00079                         get { return isStreamOwner; }
00080                         set { isStreamOwner = value; }
00081                 }
00082                 
00086                 public bool CanPatchEntries {
00087                         get { 
00088                                 return baseOutputStream.CanSeek; 
00089                         }
00090                 }
00091                 
00095                 public override bool CanRead {
00096                         get {
00097                                 return baseOutputStream.CanRead;
00098                         }
00099                 }
00100                 
00105                 public override bool CanSeek {
00106                         get {
00107                                 return false;
00108                         }
00109                 }
00110                 
00114                 public override bool CanWrite {
00115                         get {
00116                                 return baseOutputStream.CanWrite;
00117                         }
00118                 }
00119                 
00123                 public override long Length {
00124                         get {
00125                                 return baseOutputStream.Length;
00126                         }
00127                 }
00128                 
00134                 public override long Position {
00135                         get {
00136                                 return baseOutputStream.Position;
00137                         }
00138                         set {
00139                                 throw new NotSupportedException("DefalterOutputStream Position not supported");
00140                         }
00141                 }
00142                 
00147                 public override long Seek(long offset, SeekOrigin origin)
00148                 {
00149                         throw new NotSupportedException("DeflaterOutputStream Seek not supported");
00150                 }
00151                 
00156                 public override void SetLength(long val)
00157                 {
00158                         throw new NotSupportedException("DeflaterOutputStream SetLength not supported");
00159                 }
00160                 
00165                 public override int ReadByte()
00166                 {
00167                         throw new NotSupportedException("DeflaterOutputStream ReadByte not supported");
00168                 }
00169                 
00174                 public override int Read(byte[] b, int off, int len)
00175                 {
00176                         throw new NotSupportedException("DeflaterOutputStream Read not supported");
00177                 }
00178                 
00189                 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
00190                 {
00191                         throw new NotSupportedException("DeflaterOutputStream BeginRead not currently supported");
00192                 }
00193                 
00204                 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
00205                 {
00206                         throw new NotSupportedException("DeflaterOutputStream BeginWrite not currently supported");
00207                 }
00208                 
00214                 protected void Deflate()
00215                 {
00216                         while (!def.IsNeedingInput) {
00217                                 int len = def.Deflate(buf, 0, buf.Length);
00218                                 
00219                                 if (len <= 0) {
00220                                         break;
00221                                 }
00222                                 
00223                                 if (this.keys != null) {
00224                                         this.EncryptBlock(buf, 0, len);
00225                                 }
00226                                 
00227                                 baseOutputStream.Write(buf, 0, len);
00228                         }
00229                         
00230                         if (!def.IsNeedingInput) {
00231                                 throw new SharpZipBaseException("DeflaterOutputStream can't deflate all input?");
00232                         }
00233                 }
00234                 
00241                 public DeflaterOutputStream(Stream baseOutputStream) : this(baseOutputStream, new Deflater(), 512)
00242                 {
00243                 }
00244                 
00255                 public DeflaterOutputStream(Stream baseOutputStream, Deflater defl) : this(baseOutputStream, defl, 512)
00256                 {
00257                 }
00258                 
00281                 public DeflaterOutputStream(Stream baseOutputStream, Deflater deflater, int bufsize)
00282                 {
00283                         if (baseOutputStream.CanWrite == false) {
00284                                 throw new ArgumentException("baseOutputStream", "must support writing");
00285                         }
00286 
00287                         if (deflater == null) {
00288                                 throw new ArgumentNullException("deflater");
00289                         }
00290                         
00291                         if (bufsize <= 0) {
00292                                 throw new ArgumentOutOfRangeException("bufsize");
00293                         }
00294                         
00295                         this.baseOutputStream = baseOutputStream;
00296                         buf = new byte[bufsize];
00297                         def = deflater;
00298                 }
00299                 
00305                 public override void Flush()
00306                 {
00307                         def.Flush();
00308                         Deflate();
00309                         baseOutputStream.Flush();
00310                 }
00311                 
00318                 public virtual void Finish()
00319                 {
00320                         def.Finish();
00321                         while (!def.IsFinished)  {
00322                                 int len = def.Deflate(buf, 0, buf.Length);
00323                                 if (len <= 0) {
00324                                         break;
00325                                 }
00326                                 
00327                                 if (this.keys != null) {
00328                                         this.EncryptBlock(buf, 0, len);
00329                                 }
00330                                 
00331                                 baseOutputStream.Write(buf, 0, len);
00332                         }
00333                         if (!def.IsFinished) {
00334                                 throw new SharpZipBaseException("Can't deflate all input?");
00335                         }
00336                         baseOutputStream.Flush();
00337                         keys = null;
00338                 }
00339                 
00344                 public override void Close()
00345                 {
00346                         if ( !isClosed ) {
00347                                 isClosed = true;
00348                                 Finish();
00349                                 if ( isStreamOwner ) {
00350                                         baseOutputStream.Close();
00351                                 }
00352                         }
00353                 }
00354                 
00361                 public override void WriteByte(byte bval)
00362                 {
00363                         byte[] b = new byte[1];
00364                         b[0] = bval;
00365                         Write(b, 0, 1);
00366                 }
00367                 
00380                 public override void Write(byte[] buf, int off, int len)
00381                 {
00382                         def.SetInput(buf, off, len);
00383                         Deflate();
00384                 }
00385                 
00386                 #region Encryption
00387                 
00388                 // TODO:  Refactor this code.  The presence of Zip specific code in this low level class is wrong
00389                 string password = null;
00390                 uint[] keys     = null;
00391                 
00395                 public string Password {
00396                         get { 
00397                                 return password; 
00398                         }
00399                         set {
00400                                 if ( value != null && value.Length == 0 ) {
00401                                         password = null;
00402                                 } else {
00403                                         password = value; 
00404                                 }
00405                         }
00406                 }
00407                 
00408                 
00415                 protected byte EncryptByte()
00416                 {
00417                         uint temp = ((keys[2] & 0xFFFF) | 2);
00418                         return (byte)((temp * (temp ^ 1)) >> 8);
00419                 }
00420                 
00421                 
00434                 protected void EncryptBlock(byte[] buffer, int offset, int length)
00435                 {
00436                         // TODO: refactor to use crypto transform
00437                         for (int i = offset; i < offset + length; ++i) {
00438                                 byte oldbyte = buffer[i];
00439                                 buffer[i] ^= EncryptByte();
00440                                 UpdateKeys(oldbyte);
00441                         }
00442                 }
00443                 
00447                 protected void InitializePassword(string password) {
00448                         keys = new uint[] {
00449                                 0x12345678,
00450                                 0x23456789,
00451                                 0x34567890
00452                         };
00453                         
00454                         for (int i = 0; i < password.Length; ++i) {
00455                                 UpdateKeys((byte)password[i]);
00456                         }
00457                 }
00458 
00462                 protected void UpdateKeys(byte ch)
00463                 {
00464                         keys[0] = Crc32.ComputeCrc32(keys[0], ch);
00465                         keys[1] = keys[1] + (byte)keys[0];
00466                         keys[1] = keys[1] * 134775813 + 1;
00467                         keys[2] = Crc32.ComputeCrc32(keys[2], (byte)(keys[1] >> 24));
00468                 }
00469                 #endregion
00470         }
00471 }

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