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

Go to the documentation of this file.
00001 // StreamManipulator.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         
00059         public class StreamManipulator
00060         {
00061                 private byte[] window;
00062                 private int window_start = 0;
00063                 private int window_end = 0;
00064                 
00065                 private uint buffer = 0;
00066                 private int bits_in_buffer = 0;
00067                 
00076                 public int PeekBits(int n)
00077                 {
00078                         if (bits_in_buffer < n) {
00079                                 if (window_start == window_end) {
00080                                         return -1; // ok
00081                                 }
00082                                 buffer |= (uint)((window[window_start++] & 0xff |
00083                                                  (window[window_start++] & 0xff) << 8) << bits_in_buffer);
00084                                 bits_in_buffer += 16;
00085                         }
00086                         return (int)(buffer & ((1 << n) - 1));
00087                 }
00088                 
00094                 public void DropBits(int n)
00095                 {
00096                         buffer >>= n;
00097                         bits_in_buffer -= n;
00098                 }
00099                 
00107                 public int GetBits(int n)
00108                 {
00109                         int bits = PeekBits(n);
00110                         if (bits >= 0) {
00111                                 DropBits(n);
00112                         }
00113                         return bits;
00114                 }
00115                 
00123                 public int AvailableBits {
00124                         get {
00125                                 return bits_in_buffer;
00126                         }
00127                 }
00128                 
00135                 public int AvailableBytes {
00136                         get {
00137                                 return window_end - window_start + (bits_in_buffer >> 3);
00138                         }
00139                 }
00140                 
00144                 public void SkipToByteBoundary()
00145                 {
00146                         buffer >>= (bits_in_buffer & 7);
00147                         bits_in_buffer &= ~7;
00148                 }
00149 
00153                 public bool IsNeedingInput {
00154                         get {
00155                                 return window_start == window_end;
00156                         }
00157                 }
00158                 
00183                 public int CopyBytes(byte[] output, int offset, int length)
00184                 {
00185                         if (length < 0) {
00186                                 throw new ArgumentOutOfRangeException("length");
00187                         }
00188                         if ((bits_in_buffer & 7) != 0) {
00189                                 /* bits_in_buffer may only be 0 or a multiple of 8 */
00190                                 throw new InvalidOperationException("Bit buffer is not byte aligned!");
00191                         }
00192                         
00193                         int count = 0;
00194                         while (bits_in_buffer > 0 && length > 0) {
00195                                 output[offset++] = (byte) buffer;
00196                                 buffer >>= 8;
00197                                 bits_in_buffer -= 8;
00198                                 length--;
00199                                 count++;
00200                         }
00201                         
00202                         if (length == 0) {
00203                                 return count;
00204                         }
00205                         
00206                         int avail = window_end - window_start;
00207                         if (length > avail) {
00208                                 length = avail;
00209                         }
00210                         System.Array.Copy(window, window_start, output, offset, length);
00211                         window_start += length;
00212                         
00213                         if (((window_start - window_end) & 1) != 0) {
00214                                 /* We always want an even number of bytes in input, see peekBits */
00215                                 buffer = (uint)(window[window_start++] & 0xff);
00216                                 bits_in_buffer = 8;
00217                         }
00218                         return count + length;
00219                 }
00220                 
00224                 public StreamManipulator()
00225                 {
00226                 }
00227 
00228                 
00232                 public void Reset()
00233                 {
00234                         buffer = (uint)(window_start = window_end = bits_in_buffer = 0);
00235                 }
00236 
00244                 public void SetInput(byte[] buf, int off, int len)
00245                 {
00246                         if (window_start < window_end) {
00247                                 throw new InvalidOperationException("Old input was not completely processed");
00248                         }
00249                         
00250                         int end = off + len;
00251                         
00252                         /* We want to throw an ArrayIndexOutOfBoundsException early.  The
00253                         * check is very tricky: it also handles integer wrap around.
00254                         */
00255                         if (0 > off || off > end || end > buf.Length) {
00256                                 throw new ArgumentOutOfRangeException();
00257                         }
00258                         
00259                         if ((len & 1) != 0) {
00260                                 /* We always want an even number of bytes in input, see peekBits */
00261                                 buffer |= (uint)((buf[off++] & 0xff) << bits_in_buffer);
00262                                 bits_in_buffer += 8;
00263                         }
00264                         
00265                         window = buf;
00266                         window_start = off;
00267                         window_end = end;
00268                 }
00269         }
00270 }

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