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

Go to the documentation of this file.
00001 // OutputWindow.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 
00041 namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams 
00042 {
00043         
00050         public class OutputWindow
00051         {
00052                 private static int WINDOW_SIZE = 1 << 15;
00053                 private static int WINDOW_MASK = WINDOW_SIZE - 1;
00054                 
00055                 private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
00056                 private int windowEnd  = 0;
00057                 private int windowFilled = 0;
00058                 
00066                 public void Write(int abyte)
00067                 {
00068                         if (windowFilled++ == WINDOW_SIZE) {
00069                                 throw new InvalidOperationException("Window full");
00070                         }
00071                         window[windowEnd++] = (byte) abyte;
00072                         windowEnd &= WINDOW_MASK;
00073                 }
00074                 
00075                 
00076                 private void SlowRepeat(int repStart, int len, int dist)
00077                 {
00078                         while (len-- > 0) {
00079                                 window[windowEnd++] = window[repStart++];
00080                                 windowEnd &= WINDOW_MASK;
00081                                 repStart &= WINDOW_MASK;
00082                         }
00083                 }
00084                 
00093                 public void Repeat(int len, int dist)
00094                 {
00095                         if ((windowFilled += len) > WINDOW_SIZE) {
00096                                 throw new InvalidOperationException("Window full");
00097                         }
00098                         
00099                         int rep_start = (windowEnd - dist) & WINDOW_MASK;
00100                         int border = WINDOW_SIZE - len;
00101                         if (rep_start <= border && windowEnd < border) {
00102                                 if (len <= dist) {
00103                                         System.Array.Copy(window, rep_start, window, windowEnd, len);
00104                                         windowEnd += len;
00105                                 } else {
00106                                         /* We have to copy manually, since the repeat pattern overlaps. */
00107                                         while (len-- > 0) {
00108                                                 window[windowEnd++] = window[rep_start++];
00109                                         }
00110                                 }
00111                         } else {
00112                                 SlowRepeat(rep_start, len, dist);
00113                         }
00114                 }
00115                 
00122                 public int CopyStored(StreamManipulator input, int len)
00123                 {
00124                         len = Math.Min(Math.Min(len, WINDOW_SIZE - windowFilled), input.AvailableBytes);
00125                         int copied;
00126                         
00127                         int tailLen = WINDOW_SIZE - windowEnd;
00128                         if (len > tailLen) {
00129                                 copied = input.CopyBytes(window, windowEnd, tailLen);
00130                                 if (copied == tailLen) {
00131                                         copied += input.CopyBytes(window, 0, len - tailLen);
00132                                 }
00133                         } else {
00134                                 copied = input.CopyBytes(window, windowEnd, len);
00135                         }
00136                         
00137                         windowEnd = (windowEnd + copied) & WINDOW_MASK;
00138                         windowFilled += copied;
00139                         return copied;
00140                 }
00141                 
00151                 public void CopyDict(byte[] dict, int offset, int len)
00152                 {
00153                         if (windowFilled > 0) {
00154                                 throw new InvalidOperationException();
00155                         }
00156                         
00157                         if (len > WINDOW_SIZE) {
00158                                 offset += len - WINDOW_SIZE;
00159                                 len = WINDOW_SIZE;
00160                         }
00161                         System.Array.Copy(dict, offset, window, 0, len);
00162                         windowEnd = len & WINDOW_MASK;
00163                 }
00164 
00169                 public int GetFreeSpace()
00170                 {
00171                         return WINDOW_SIZE - windowFilled;
00172                 }
00173                 
00178                 public int GetAvailable()
00179                 {
00180                         return windowFilled;
00181                 }
00182 
00193                 public int CopyOutput(byte[] output, int offset, int len)
00194                 {
00195                         int copy_end = windowEnd;
00196                         if (len > windowFilled) {
00197                                 len = windowFilled;
00198                         } else {
00199                                 copy_end = (windowEnd - windowFilled + len) & WINDOW_MASK;
00200                         }
00201                         
00202                         int copied = len;
00203                         int tailLen = len - copy_end;
00204                         
00205                         if (tailLen > 0) {
00206                                 System.Array.Copy(window, WINDOW_SIZE - tailLen, output, offset, tailLen);
00207                                 offset += tailLen;
00208                                 len = copy_end;
00209                         }
00210                         System.Array.Copy(window, copy_end - len, output, offset, len);
00211                         windowFilled -= copied;
00212                         if (windowFilled < 0) {
00213                                 throw new InvalidOperationException();
00214                         }
00215                         return copied;
00216                 }
00217 
00221                 public void Reset()
00222                 {
00223                         windowFilled = windowEnd = 0;
00224                 }
00225         }
00226 }

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