Skip to content
This repository
Browse code

Add initial cut of LZW. Not yet included in repository projects as th…

…e code is not well tested...
  • Loading branch information...
commit 405fdd64925de045ce528b4f1bdc0308ab1587fb 1 parent 6da2d63
John Reilly jfreilly authored
94 src/Lzw/LzwConstants.cs
... ... @@ -0,0 +1,94 @@
  1 +// LzwConstants.cs
  2 +//
  3 +// Copyright (C) 2009 Gabriel Burca
  4 +//
  5 +// This program is free software; you can redistribute it and/or
  6 +// modify it under the terms of the GNU General Public License
  7 +// as published by the Free Software Foundation; either version 2
  8 +// of the License, or (at your option) any later version.
  9 +//
  10 +// This program is distributed in the hope that it will be useful,
  11 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 +// GNU General Public License for more details.
  14 +//
  15 +// You should have received a copy of the GNU General Public License
  16 +// along with this program; if not, write to the Free Software
  17 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18 +//
  19 +// Linking this library statically or dynamically with other modules is
  20 +// making a combined work based on this library. Thus, the terms and
  21 +// conditions of the GNU General Public License cover the whole
  22 +// combination.
  23 +//
  24 +// As a special exception, the copyright holders of this library give you
  25 +// permission to link this library with independent modules to produce an
  26 +// executable, regardless of the license terms of these independent
  27 +// modules, and to copy and distribute the resulting executable under
  28 +// terms of your choice, provided that you also meet, for each linked
  29 +// independent module, the terms and conditions of the license of that
  30 +// module. An independent module is a module which is not derived from
  31 +// or based on this library. If you modify this library, you may extend
  32 +// this exception to your version of the library, but you are not
  33 +// obligated to do so. If you do not wish to do so, delete this
  34 +// exception statement from your version.
  35 +
  36 +namespace ICSharpCode.SharpZipLib.LZW {
  37 +
  38 + /// <summary>
  39 + /// This class contains constants used for LZW
  40 + /// </summary>
  41 + sealed public class LzwConstants {
  42 + /// <summary>
  43 + /// Magic number found at start of LZW header: 0x1f 0x9d
  44 + /// </summary>
  45 + public const int MAGIC = 0x1f9d;
  46 +
  47 + /// <summary>
  48 + /// Maximum number of bits per code
  49 + /// </summary>
  50 + public const int MAX_BITS = 16;
  51 +
  52 + /* 3rd header byte:
  53 + * bit 0..4 Number of compression bits
  54 + * bit 5 Extended header
  55 + * bit 6 Free
  56 + * bit 7 Block mode
  57 + */
  58 +
  59 + /// <summary>
  60 + /// Mask for 'number of compression bits'
  61 + /// </summary>
  62 + public const int BIT_MASK = 0x1f;
  63 +
  64 + /// <summary>
  65 + /// Indicates the presence of a fourth header byte
  66 + /// </summary>
  67 + public const int EXTENDED_MASK = 0x20;
  68 + //public const int FREE_MASK = 0x40;
  69 +
  70 + /// <summary>
  71 + /// Reserved bits
  72 + /// </summary>
  73 + public const int RESERVED_MASK = 0x60;
  74 +
  75 + /// <summary>
  76 + /// Block compression: if table is full and compression rate is dropping,
  77 + /// clear the dictionary.
  78 + /// </summary>
  79 + public const int BLOCK_MODE_MASK = 0x80;
  80 +
  81 + /// <summary>
  82 + /// LZW file header size (in bytes)
  83 + /// </summary>
  84 + public const int HDR_SIZE = 3;
  85 +
  86 + /// <summary>
  87 + /// Initial number of bits per code
  88 + /// </summary>
  89 + public const int INIT_BITS = 9;
  90 +
  91 + LzwConstants() {
  92 + }
  93 + }
  94 +}
88 src/Lzw/LzwException.cs
... ... @@ -0,0 +1,88 @@
  1 +// LzwException.cs
  2 +//
  3 +// Copyright (C) 2009 Gabriel Burca
  4 +//
  5 +// This program is free software; you can redistribute it and/or
  6 +// modify it under the terms of the GNU General Public License
  7 +// as published by the Free Software Foundation; either version 2
  8 +// of the License, or (at your option) any later version.
  9 +//
  10 +// This program is distributed in the hope that it will be useful,
  11 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 +// GNU General Public License for more details.
  14 +//
  15 +// You should have received a copy of the GNU General Public License
  16 +// along with this program; if not, write to the Free Software
  17 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18 +//
  19 +// Linking this library statically or dynamically with other modules is
  20 +// making a combined work based on this library. Thus, the terms and
  21 +// conditions of the GNU General Public License cover the whole
  22 +// combination.
  23 +//
  24 +// As a special exception, the copyright holders of this library give you
  25 +// permission to link this library with independent modules to produce an
  26 +// executable, regardless of the license terms of these independent
  27 +// modules, and to copy and distribute the resulting executable under
  28 +// terms of your choice, provided that you also meet, for each linked
  29 +// independent module, the terms and conditions of the license of that
  30 +// module. An independent module is a module which is not derived from
  31 +// or based on this library. If you modify this library, you may extend
  32 +// this exception to your version of the library, but you are not
  33 +// obligated to do so. If you do not wish to do so, delete this
  34 +// exception statement from your version.
  35 +
  36 +using System;
  37 +
  38 +#if !NETCF_1_0 && !NETCF_2_0
  39 +using System.Runtime.Serialization;
  40 +#endif
  41 +
  42 +namespace ICSharpCode.SharpZipLib.LZW
  43 +{
  44 +
  45 + /// <summary>
  46 + /// LzwException represents a LZW specific exception
  47 + /// </summary>
  48 +#if !NETCF_1_0 && !NETCF_2_0
  49 + [Serializable]
  50 +#endif
  51 + public class LzwException : SharpZipBaseException
  52 + {
  53 +
  54 +#if !NETCF_1_0 && !NETCF_2_0
  55 + /// <summary>
  56 + /// Deserialization constructor
  57 + /// </summary>
  58 + /// <param name="info"><see cref="SerializationInfo"/> for this constructor</param>
  59 + /// <param name="context"><see cref="StreamingContext"/> for this constructor</param>
  60 + protected LzwException(SerializationInfo info, StreamingContext context)
  61 + : base(info, context) {
  62 + }
  63 +#endif
  64 +
  65 + /// <summary>
  66 + /// Initialise a new instance of LzwException
  67 + /// </summary>
  68 + public LzwException() {
  69 + }
  70 +
  71 + /// <summary>
  72 + /// Initialise a new instance of LzwException with its message string.
  73 + /// </summary>
  74 + /// <param name="message">A <see cref="string"/> that describes the error.</param>
  75 + public LzwException(string message)
  76 + : base(message) {
  77 + }
  78 +
  79 + /// <summary>
  80 + /// Initialise a new instance of <see cref="LzwException"></see>.
  81 + /// </summary>
  82 + /// <param name="message">A <see cref="string"/> that describes the error.</param>
  83 + /// <param name="innerException">The <see cref="Exception"/> that caused this exception.</param>
  84 + public LzwException(string message, Exception innerException)
  85 + : base(message, innerException) {
  86 + }
  87 + }
  88 +}
598 src/Lzw/LzwInputStream.cs
... ... @@ -0,0 +1,598 @@
  1 +// LzwInputStream.cs
  2 +//
  3 +// Copyright (C) 2009 Gabriel Burca
  4 +//
  5 +// This program is free software; you can redistribute it and/or
  6 +// modify it under the terms of the GNU General Public License
  7 +// as published by the Free Software Foundation; either version 2
  8 +// of the License, or (at your option) any later version.
  9 +//
  10 +// This program is distributed in the hope that it will be useful,
  11 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 +// GNU General Public License for more details.
  14 +//
  15 +// You should have received a copy of the GNU General Public License
  16 +// along with this program; if not, write to the Free Software
  17 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18 +//
  19 +// Linking this library statically or dynamically with other modules is
  20 +// making a combined work based on this library. Thus, the terms and
  21 +// conditions of the GNU General Public License cover the whole
  22 +// combination.
  23 +//
  24 +// As a special exception, the copyright holders of this library give you
  25 +// permission to link this library with independent modules to produce an
  26 +// executable, regardless of the license terms of these independent
  27 +// modules, and to copy and distribute the resulting executable under
  28 +// terms of your choice, provided that you also meet, for each linked
  29 +// independent module, the terms and conditions of the license of that
  30 +// module. An independent module is a module which is not derived from
  31 +// or based on this library. If you modify this library, you may extend
  32 +// this exception to your version of the library, but you are not
  33 +// obligated to do so. If you do not wish to do so, delete this
  34 +// exception statement from your version.
  35 +
  36 +using System;
  37 +using System.IO;
  38 +
  39 +namespace ICSharpCode.SharpZipLib.LZW
  40 +{
  41 +
  42 + /// <summary>
  43 + /// This filter stream is used to decompress a LZW format stream.
  44 + /// Specifically, a stream that uses the LZC compression method.
  45 + /// This file format is usually associated with the .Z file extension.
  46 + ///
  47 + /// See http://en.wikipedia.org/wiki/Compress
  48 + /// See http://wiki.wxwidgets.org/Development:_Z_File_Format
  49 + ///
  50 + /// The file header consists of 3 (or optionally 4) bytes. The first two bytes
  51 + /// contain the magic marker "0x1f 0x9d", followed by a byte of flags.
  52 + ///
  53 + /// Based on Java code by Ronald Tschalar, which in turn was based on the unlzw.c
  54 + /// code in the gzip package.
  55 + /// </summary>
  56 + /// <example> This sample shows how to unzip a compressed file
  57 + /// <code>
  58 + /// using System;
  59 + /// using System.IO;
  60 + ///
  61 + /// using ICSharpCode.SharpZipLib.Core;
  62 + /// using ICSharpCode.SharpZipLib.LZW;
  63 + ///
  64 + /// class MainClass
  65 + /// {
  66 + /// public static void Main(string[] args)
  67 + /// {
  68 + /// using (Stream inStream = new LzwInputStream(File.OpenRead(args[0])))
  69 + /// using (FileStream outStream = File.Create(Path.GetFileNameWithoutExtension(args[0]))) {
  70 + /// byte[] buffer = new byte[4096];
  71 + /// StreamUtils.Copy(inStream, outStream, buffer);
  72 + /// // OR
  73 + /// inStream.Read(buffer, 0, buffer.Length);
  74 + /// // now do something with the buffer
  75 + /// }
  76 + /// }
  77 + /// }
  78 + /// </code>
  79 + /// </example>
  80 + public class LzwInputStream : Stream
  81 + {
  82 + /// <summary>
  83 + /// Get/set flag indicating ownership of underlying stream.
  84 + /// When the flag is true <see cref="Close"/> will close the underlying stream also.
  85 + /// </summary>
  86 + /// <remarks>
  87 + /// The default value is true.
  88 + /// </remarks>
  89 + public bool IsStreamOwner
  90 + {
  91 + get { return isStreamOwner; }
  92 + set { isStreamOwner = value; }
  93 + }
  94 +
  95 + /// <summary>
  96 + /// Creates a LzwInputStream
  97 + /// </summary>
  98 + /// <param name="baseInputStream">
  99 + /// The stream to read compressed data from (baseInputStream LZW format)
  100 + /// </param>
  101 + public LzwInputStream(Stream baseInputStream) {
  102 + this.baseInputStream = baseInputStream;
  103 + }
  104 +
  105 + /// <summary>
  106 + /// See <see cref="System.IO.Stream.ReadByte"/>
  107 + /// </summary>
  108 + /// <returns></returns>
  109 + public override int ReadByte() {
  110 + int b = Read(one, 0, 1);
  111 + if (b == 1)
  112 + return (one[0] & 0xff);
  113 + return -1;
  114 + }
  115 +
  116 + /// <summary>
  117 + /// Reads decompressed data into the provided buffer byte array
  118 + /// </summary>
  119 + /// <param name ="buffer">
  120 + /// The array to read and decompress data into
  121 + /// </param>
  122 + /// <param name ="offset">
  123 + /// The offset indicating where the data should be placed
  124 + /// </param>
  125 + /// <param name ="count">
  126 + /// The number of bytes to decompress
  127 + /// </param>
  128 + /// <returns>The number of bytes read. Zero signals the end of stream</returns>
  129 + public override int Read(byte[] buffer, int offset, int count) {
  130 + if (!headerParsed) ParseHeader();
  131 +
  132 + if (eof) return -1;
  133 + int start = offset;
  134 +
  135 + /* Using local copies of various variables speeds things up by as
  136 + * much as 30% in Java! Performance not tested in C#.
  137 + */
  138 + int[] lTabPrefix = tabPrefix;
  139 + byte[] lTabSuffix = tabSuffix;
  140 + byte[] lStack = stack;
  141 + int lNBits = nBits;
  142 + int lMaxCode = maxCode;
  143 + int lMaxMaxCode = maxMaxCode;
  144 + int lBitMask = bitMask;
  145 + int lOldCode = oldCode;
  146 + byte lFinChar = finChar;
  147 + int lStackP = stackP;
  148 + int lFreeEnt = freeEnt;
  149 + byte[] lData = data;
  150 + int lBitPos = bitPos;
  151 +
  152 +
  153 + // empty stack if stuff still left
  154 + int sSize = lStack.Length - lStackP;
  155 + if (sSize > 0) {
  156 + int num = (sSize >= count) ? count : sSize;
  157 + Array.Copy(lStack, lStackP, buffer, offset, num);
  158 + offset += num;
  159 + count -= num;
  160 + lStackP += num;
  161 + }
  162 +
  163 + if (count == 0) {
  164 + stackP = lStackP;
  165 + return offset - start;
  166 + }
  167 +
  168 +
  169 + // loop, filling local buffer until enough data has been decompressed
  170 + MainLoop: do {
  171 + if (end < EXTRA) {
  172 + Fill();
  173 + }
  174 +
  175 + int bitIn = (got > 0) ? (end - end % lNBits) << 3 :
  176 + (end << 3) - (lNBits - 1);
  177 +
  178 + while (lBitPos < bitIn) {
  179 + #region A
  180 + // handle 1-byte reads correctly
  181 + if (count == 0) {
  182 + nBits = lNBits;
  183 + maxCode = lMaxCode;
  184 + maxMaxCode = lMaxMaxCode;
  185 + bitMask = lBitMask;
  186 + oldCode = lOldCode;
  187 + finChar = lFinChar;
  188 + stackP = lStackP;
  189 + freeEnt = lFreeEnt;
  190 + bitPos = lBitPos;
  191 +
  192 + return offset - start;
  193 + }
  194 +
  195 + // check for code-width expansion
  196 + if (lFreeEnt > lMaxCode) {
  197 + int nBytes = lNBits << 3;
  198 + lBitPos = (lBitPos - 1) +
  199 + nBytes - (lBitPos - 1 + nBytes) % nBytes;
  200 +
  201 + lNBits++;
  202 + lMaxCode = (lNBits == maxBits) ? lMaxMaxCode :
  203 + (1 << lNBits) - 1;
  204 +
  205 + lBitMask = (1 << lNBits) - 1;
  206 + lBitPos = ResetBuf(lBitPos);
  207 + goto MainLoop;
  208 + }
  209 + #endregion
  210 +
  211 + #region B
  212 + // read next code
  213 + int pos = lBitPos >> 3;
  214 + int code = (((lData[pos] & 0xFF) |
  215 + ((lData[pos + 1] & 0xFF) << 8) |
  216 + ((lData[pos + 2] & 0xFF) << 16)) >>
  217 + (lBitPos & 0x7)) & lBitMask;
  218 +
  219 + lBitPos += lNBits;
  220 +
  221 + // handle first iteration
  222 + if (lOldCode == -1) {
  223 + if (code >= 256) throw new LzwException("corrupt input: " + code + " > 255");
  224 +
  225 + lFinChar = (byte) (lOldCode = code);
  226 + buffer[offset++] = lFinChar;
  227 + count--;
  228 + continue;
  229 + }
  230 +
  231 + // handle CLEAR code
  232 + if (code == TBL_CLEAR && blockMode) {
  233 + Array.Copy(zeros, 0, lTabPrefix, 0, zeros.Length);
  234 + lFreeEnt = TBL_FIRST - 1;
  235 +
  236 + int nBytes = lNBits << 3;
  237 + lBitPos = (lBitPos - 1) + nBytes - (lBitPos - 1 + nBytes) % nBytes;
  238 + lNBits = LzwConstants.INIT_BITS;
  239 + lMaxCode = (1 << lNBits) - 1;
  240 + lBitMask = lMaxCode;
  241 +
  242 + // Code tables reset
  243 +
  244 + lBitPos = ResetBuf(lBitPos);
  245 + goto MainLoop;
  246 + }
  247 + #endregion
  248 +
  249 + #region C
  250 + // setup
  251 + int inCode = code;
  252 + lStackP = lStack.Length;
  253 +
  254 + // Handle KwK case
  255 + if (code >= lFreeEnt) {
  256 + if (code > lFreeEnt) {
  257 + throw new LzwException("corrupt input: code=" + code +
  258 + ", freeEnt=" + lFreeEnt);
  259 + }
  260 +
  261 + lStack[--lStackP] = lFinChar;
  262 + code = lOldCode;
  263 + }
  264 +
  265 + // Generate output characters in reverse order
  266 + while (code >= 256) {
  267 + lStack[--lStackP] = lTabSuffix[code];
  268 + code = lTabPrefix[code];
  269 + }
  270 +
  271 + lFinChar = lTabSuffix[code];
  272 + buffer[offset++] = lFinChar;
  273 + count--;
  274 +
  275 + // And put them out in forward order
  276 + sSize = lStack.Length - lStackP;
  277 + int num = (sSize >= count) ? count : sSize;
  278 + Array.Copy(lStack, lStackP, buffer, offset, num);
  279 + offset += num;
  280 + count -= num;
  281 + lStackP += num;
  282 + #endregion
  283 +
  284 + #region D
  285 + // generate new entry in table
  286 + if (lFreeEnt < lMaxMaxCode) {
  287 + lTabPrefix[lFreeEnt] = lOldCode;
  288 + lTabSuffix[lFreeEnt] = lFinChar;
  289 + lFreeEnt++;
  290 + }
  291 +
  292 + // Remember previous code
  293 + lOldCode = inCode;
  294 +
  295 + // if output buffer full, then return
  296 + if (count == 0) {
  297 + nBits = lNBits;
  298 + maxCode = lMaxCode;
  299 + bitMask = lBitMask;
  300 + oldCode = lOldCode;
  301 + finChar = lFinChar;
  302 + stackP = lStackP;
  303 + freeEnt = lFreeEnt;
  304 + bitPos = lBitPos;
  305 +
  306 + return offset - start;
  307 + }
  308 + #endregion
  309 + } // while
  310 +
  311 + lBitPos = ResetBuf(lBitPos);
  312 +
  313 + } while (got > 0); // do..while
  314 +
  315 + nBits = lNBits;
  316 + maxCode = lMaxCode;
  317 + bitMask = lBitMask;
  318 + oldCode = lOldCode;
  319 + finChar = lFinChar;
  320 + stackP = lStackP;
  321 + freeEnt = lFreeEnt;
  322 + bitPos = lBitPos;
  323 +
  324 + eof = true;
  325 + return offset - start;
  326 + }
  327 +
  328 + /// <summary>
  329 + /// Moves the unread data in the buffer to the beginning and resets
  330 + /// the pointers.
  331 + /// </summary>
  332 + /// <param name="bitPosition"></param>
  333 + /// <returns></returns>
  334 + private int ResetBuf(int bitPosition) {
  335 + int pos = bitPosition >> 3;
  336 + Array.Copy(data, pos, data, 0, end - pos);
  337 + end -= pos;
  338 + return 0;
  339 + }
  340 +
  341 +
  342 + private void Fill() {
  343 + got = baseInputStream.Read(data, end, data.Length - 1 - end);
  344 + if (got > 0) {
  345 + end += got;
  346 + }
  347 + }
  348 +
  349 +
  350 + private void ParseHeader() {
  351 + headerParsed = true;
  352 +
  353 + byte[] hdr = new byte[LzwConstants.HDR_SIZE];
  354 +
  355 + int result = baseInputStream.Read(hdr, 0, hdr.Length);
  356 +
  357 + // Check the magic marker
  358 + if (result < 0)
  359 + throw new LzwException("Failed to read LZW header");
  360 +
  361 + if (hdr[0] != (LzwConstants.MAGIC >> 8) || hdr[1] != (LzwConstants.MAGIC & 0xff)) {
  362 + throw new LzwException(String.Format(
  363 + "Wrong LZW header. Magic bytes don't match. 0x{0:x2} 0x{1:x2}",
  364 + hdr[0], hdr[1]));
  365 + }
  366 +
  367 + // Check the 3rd header byte
  368 + blockMode = (hdr[2] & LzwConstants.BLOCK_MODE_MASK) > 0;
  369 + maxBits = hdr[2] & LzwConstants.BIT_MASK;
  370 +
  371 + if (maxBits > LzwConstants.MAX_BITS) {
  372 + throw new LzwException("Stream compressed with " + maxBits +
  373 + " bits, but decompression can only handle " +
  374 + LzwConstants.MAX_BITS + " bits.");
  375 + }
  376 +
  377 + if ((hdr[2] & LzwConstants.RESERVED_MASK) > 0) {
  378 + throw new LzwException("Unsupported bits set in the header.");
  379 + }
  380 +
  381 + // Initialize variables
  382 + maxMaxCode = 1 << maxBits;
  383 + nBits = LzwConstants.INIT_BITS;
  384 + maxCode = (1 << nBits) - 1;
  385 + bitMask = maxCode;
  386 + oldCode = -1;
  387 + finChar = 0;
  388 + freeEnt = blockMode ? TBL_FIRST : 256;
  389 +
  390 + tabPrefix = new int[1 << maxBits];
  391 + tabSuffix = new byte[1 << maxBits];
  392 + stack = new byte[1 << maxBits];
  393 + stackP = stack.Length;
  394 +
  395 + for (int idx = 255; idx >= 0; idx--)
  396 + tabSuffix[idx] = (byte)idx;
  397 + }
  398 +
  399 + #region Stream Overrides
  400 + /// <summary>
  401 + /// Gets a value indicating whether the current stream supports reading
  402 + /// </summary>
  403 + public override bool CanRead
  404 + {
  405 + get
  406 + {
  407 + return baseInputStream.CanRead;
  408 + }
  409 + }
  410 +
  411 + /// <summary>
  412 + /// Gets a value of false indicating seeking is not supported for this stream.
  413 + /// </summary>
  414 + public override bool CanSeek
  415 + {
  416 + get
  417 + {
  418 + return false;
  419 + }
  420 + }
  421 +
  422 + /// <summary>
  423 + /// Gets a value of false indicating that this stream is not writeable.
  424 + /// </summary>
  425 + public override bool CanWrite
  426 + {
  427 + get
  428 + {
  429 + return false;
  430 + }
  431 + }
  432 +
  433 + /// <summary>
  434 + /// A value representing the length of the stream in bytes.
  435 + /// </summary>
  436 + public override long Length
  437 + {
  438 + get
  439 + {
  440 + return got;
  441 + }
  442 + }
  443 +
  444 + /// <summary>
  445 + /// The current position within the stream.
  446 + /// Throws a NotSupportedException when attempting to set the position
  447 + /// </summary>
  448 + /// <exception cref="NotSupportedException">Attempting to set the position</exception>
  449 + public override long Position
  450 + {
  451 + get
  452 + {
  453 + return baseInputStream.Position;
  454 + }
  455 + set
  456 + {
  457 + throw new NotSupportedException("InflaterInputStream Position not supported");
  458 + }
  459 + }
  460 +
  461 + /// <summary>
  462 + /// Flushes the baseInputStream
  463 + /// </summary>
  464 + public override void Flush()
  465 + {
  466 + baseInputStream.Flush();
  467 + }
  468 +
  469 + /// <summary>
  470 + /// Sets the position within the current stream
  471 + /// Always throws a NotSupportedException
  472 + /// </summary>
  473 + /// <param name="offset">The relative offset to seek to.</param>
  474 + /// <param name="origin">The <see cref="SeekOrigin"/> defining where to seek from.</param>
  475 + /// <returns>The new position in the stream.</returns>
  476 + /// <exception cref="NotSupportedException">Any access</exception>
  477 + public override long Seek(long offset, SeekOrigin origin)
  478 + {
  479 + throw new NotSupportedException("Seek not supported");
  480 + }
  481 +
  482 + /// <summary>
  483 + /// Set the length of the current stream
  484 + /// Always throws a NotSupportedException
  485 + /// </summary>
  486 + /// <param name="value">The new length value for the stream.</param>
  487 + /// <exception cref="NotSupportedException">Any access</exception>
  488 + public override void SetLength(long value)
  489 + {
  490 + throw new NotSupportedException("InflaterInputStream SetLength not supported");
  491 + }
  492 +
  493 + /// <summary>
  494 + /// Writes a sequence of bytes to stream and advances the current position
  495 + /// This method always throws a NotSupportedException
  496 + /// </summary>
  497 + /// <param name="buffer">Thew buffer containing data to write.</param>
  498 + /// <param name="offset">The offset of the first byte to write.</param>
  499 + /// <param name="count">The number of bytes to write.</param>
  500 + /// <exception cref="NotSupportedException">Any access</exception>
  501 + public override void Write(byte[] buffer, int offset, int count)
  502 + {
  503 + throw new NotSupportedException("InflaterInputStream Write not supported");
  504 + }
  505 +
  506 + /// <summary>
  507 + /// Writes one byte to the current stream and advances the current position
  508 + /// Always throws a NotSupportedException
  509 + /// </summary>
  510 + /// <param name="value">The byte to write.</param>
  511 + /// <exception cref="NotSupportedException">Any access</exception>
  512 + public override void WriteByte(byte value)
  513 + {
  514 + throw new NotSupportedException("InflaterInputStream WriteByte not supported");
  515 + }
  516 +
  517 + /// <summary>
  518 + /// Entry point to begin an asynchronous write. Always throws a NotSupportedException.
  519 + /// </summary>
  520 + /// <param name="buffer">The buffer to write data from</param>
  521 + /// <param name="offset">Offset of first byte to write</param>
  522 + /// <param name="count">The maximum number of bytes to write</param>
  523 + /// <param name="callback">The method to be called when the asynchronous write operation is completed</param>
  524 + /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests</param>
  525 + /// <returns>An <see cref="System.IAsyncResult">IAsyncResult</see> that references the asynchronous write</returns>
  526 + /// <exception cref="NotSupportedException">Any access</exception>
  527 + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
  528 + {
  529 + throw new NotSupportedException("InflaterInputStream BeginWrite not supported");
  530 + }
  531 +
  532 + /// <summary>
  533 + /// Closes the input stream. When <see cref="IsStreamOwner"></see>
  534 + /// is true the underlying stream is also closed.
  535 + /// </summary>
  536 + public override void Close()
  537 + {
  538 + if (!isClosed)
  539 + {
  540 + isClosed = true;
  541 + if (isStreamOwner)
  542 + {
  543 + baseInputStream.Close();
  544 + }
  545 + }
  546 + }
  547 +
  548 + #endregion
  549 +
  550 + #region Instance Fields
  551 +
  552 + Stream baseInputStream;
  553 +
  554 + /// <summary>
  555 + /// Flag indicating wether this instance is designated the stream owner.
  556 + /// When closing if this flag is true the underlying stream is closed.
  557 + /// </summary>
  558 + bool isStreamOwner = true;
  559 +
  560 + /// <summary>
  561 + /// Flag indicating wether this instance has been closed or not.
  562 + /// </summary>
  563 + bool isClosed;
  564 +
  565 + readonly byte[] one = new byte[1];
  566 + bool headerParsed;
  567 +
  568 + // string table stuff
  569 + private const int TBL_CLEAR = 0x100;
  570 + private const int TBL_FIRST = TBL_CLEAR + 1;
  571 +
  572 + private int[] tabPrefix;
  573 + private byte[] tabSuffix;
  574 + private readonly int[] zeros = new int[256];
  575 + private byte[] stack;
  576 +
  577 + // various state
  578 + private bool blockMode;
  579 + private int nBits;
  580 + private int maxBits;
  581 + private int maxMaxCode;
  582 + private int maxCode;
  583 + private int bitMask;
  584 + private int oldCode;
  585 + private byte finChar;
  586 + private int stackP;
  587 + private int freeEnt;
  588 +
  589 + // input buffer
  590 + private readonly byte[] data = new byte[1024 * 8];
  591 + private int bitPos;
  592 + private int end;
  593 + int got;
  594 + private bool eof;
  595 + private const int EXTRA = 64;
  596 + #endregion
  597 + }
  598 +}

0 comments on commit 405fdd6

Please sign in to comment.
Something went wrong with that request. Please try again.