⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deflater.cs

📁 P2P (peer to peer) file sharing program in C#. Supports Gnutella, Gnutella2, eDonkey, and OpenNap. w
💻 CS
📖 第 1 页 / 共 2 页
字号:
		/// </summary>
		public bool IsFinished 
		{
			get 
			{
				return state == FINISHED_STATE && pending.IsFlushed;
			}
		}
		
		/// <summary>
		/// Returns true, if the input buffer is empty.
		/// You should then call setInput(). 
		/// NOTE: This method can also return true when the stream
		/// was finished.
		/// </summary>
		public bool IsNeedingInput 
		{
			get 
			{
				return engine.NeedsInput();
			}
		}
		
		/// <summary>
		/// Sets the data which should be compressed next.  This should be only
		/// called when needsInput indicates that more input is needed.
		/// If you call setInput when needsInput() returns false, the
		/// previous input that is still pending will be thrown away.
		/// The given byte array should not be changed, before needsInput() returns
		/// true again.
		/// This call is equivalent to <code>setInput(input, 0, input.length)</code>.
		/// </summary>
		/// <param name="input">
		/// the buffer containing the input data.
		/// </param>
		/// <exception cref="System.InvalidOperationException">
		/// if the buffer was finished() or ended().
		/// </exception>
		public void SetInput(byte[] input)
		{
			SetInput(input, 0, input.Length);
		}
		
		/// <summary>
		/// Sets the data which should be compressed next.  This should be
		/// only called when needsInput indicates that more input is needed.
		/// The given byte array should not be changed, before needsInput() returns
		/// true again.
		/// </summary>
		/// <param name="input">
		/// the buffer containing the input data.
		/// </param>
		/// <param name="off">
		/// the start of the data.
		/// </param>
		/// <param name="len">
		/// the length of the data.
		/// </param>
		/// <exception cref="System.InvalidOperationException">
		/// if the buffer was finished() or ended() or if previous input is still pending.
		/// </exception>
		public void SetInput(byte[] input, int off, int len)
		{
			if ((state & IS_FINISHING) != 0) 
			{
				throw new InvalidOperationException("finish()/end() already called");
			}
			engine.SetInput(input, off, len);
		}
		
		/// <summary>
		/// Sets the compression level.  There is no guarantee of the exact
		/// position of the change, but if you call this when needsInput is
		/// true the change of compression level will occur somewhere near
		/// before the end of the so far given input.
		/// </summary>
		/// <param name="lvl">
		/// the new compression level.
		/// </param>
		public void SetLevel(int lvl)
		{
			if (lvl == DEFAULT_COMPRESSION) 
			{
				lvl = 6;
			} 
			else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) 
			{
				throw new ArgumentOutOfRangeException("lvl");
			}
			
			
			if (level != lvl) 
			{
				level = lvl;
				engine.SetLevel(lvl);
			}
		}
		
		/// <summary>
		/// Sets the compression strategy. Strategy is one of
		/// DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED.  For the exact
		/// position where the strategy is changed, the same as for
		/// setLevel() applies.
		/// </summary>
		/// <param name="stgy">
		/// the new compression strategy.
		/// </param>
		public void SetStrategy(DeflateStrategy stgy)
		{
			engine.Strategy = stgy;
		}
		
		/// <summary>
		/// Deflates the current input block to the given array.  It returns
		/// the number of bytes compressed, or 0 if either
		/// needsInput() or finished() returns true or length is zero.
		/// </summary>
		/// <param name="output">
		/// the buffer where to write the compressed data.
		/// </param>
		public int Deflate(byte[] output)
		{
			return Deflate(output, 0, output.Length);
		}
		
		/// <summary>
		/// Deflates the current input block to the given array.  It returns
		/// the number of bytes compressed, or 0 if either
		/// needsInput() or finished() returns true or length is zero.
		/// </summary>
		/// <param name="output">
		/// the buffer where to write the compressed data.
		/// </param>
		/// <param name="offset">
		/// the offset into the output array.
		/// </param>
		/// <param name="length">
		/// the maximum number of bytes that may be written.
		/// </param>
		/// <exception cref="System.InvalidOperationException">
		/// if end() was called.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// if offset and/or length don't match the array length.
		/// </exception>
		public int Deflate(byte[] output, int offset, int length)
		{
			int origLength = length;
			
			if (state == CLOSED_STATE) 
			{
				throw new InvalidOperationException("Deflater closed");
			}
			
			if (state < BUSY_STATE) 
			{
				/* output header */
				int header = (DEFLATED +
					((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
				int level_flags = (level - 1) >> 1;
				if (level_flags < 0 || level_flags > 3) 
				{
					level_flags = 3;
				}
				header |= level_flags << 6;
				if ((state & IS_SETDICT) != 0) 
				{
					/* Dictionary was set */
					header |= DeflaterConstants.PRESET_DICT;
				}
				header += 31 - (header % 31);
				
				
				pending.WriteShortMSB(header);
				if ((state & IS_SETDICT) != 0) 
				{
					int chksum = engine.Adler;
					engine.ResetAdler();
					pending.WriteShortMSB(chksum >> 16);
					pending.WriteShortMSB(chksum & 0xffff);
				}
				
				state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
			}
			
			for (;;) 
			{
				int count = pending.Flush(output, offset, length);
				offset   += count;
				totalOut += count;
				length   -= count;
				
				if (length == 0 || state == FINISHED_STATE) 
				{
					break;
				}
				
				if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) 
				{
					if (state == BUSY_STATE) 
					{
						/* We need more input now */
						return origLength - length;
					} 
					else if (state == FLUSHING_STATE) 
					{
						if (level != NO_COMPRESSION) 
						{
							/* We have to supply some lookahead.  8 bit lookahead
							 * are needed by the zlib inflater, and we must fill
							 * the next byte, so that all bits are flushed.
							 */
							int neededbits = 8 + ((-pending.BitCount) & 7);
							while (neededbits > 0) 
							{
								/* write a static tree block consisting solely of
								 * an EOF:
								 */
								pending.WriteBits(2, 10);
								neededbits -= 10;
							}
						}
						state = BUSY_STATE;
					} 
					else if (state == FINISHING_STATE) 
					{
						pending.AlignToByte();
						/* We have completed the stream */
						if (!noHeader) 
						{
							int adler = engine.Adler;
							pending.WriteShortMSB(adler >> 16);
							pending.WriteShortMSB(adler & 0xffff);
						}
						state = FINISHED_STATE;
					}
				}
			}
			return origLength - length;
		}
		
		/// <summary>
		/// Sets the dictionary which should be used in the deflate process.
		/// This call is equivalent to <code>setDictionary(dict, 0, dict.Length)</code>.
		/// </summary>
		/// <param name="dict">
		/// the dictionary.
		/// </param>
		/// <exception cref="System.InvalidOperationException">
		/// if setInput () or deflate () were already called or another dictionary was already set.
		/// </exception>
		public void SetDictionary(byte[] dict)
		{
			SetDictionary(dict, 0, dict.Length);
		}
		
		/// <summary>
		/// Sets the dictionary which should be used in the deflate process.
		/// The dictionary should be a byte array containing strings that are
		/// likely to occur in the data which should be compressed.  The
		/// dictionary is not stored in the compressed output, only a
		/// checksum.  To decompress the output you need to supply the same
		/// dictionary again.
		/// </summary>
		/// <param name="dict">
		/// the dictionary.
		/// </param>
		/// <param name="offset">
		/// an offset into the dictionary.
		/// </param>
		/// <param name="length">
		/// the length of the dictionary.
		/// </param>
		/// <exception cref="System.InvalidOperationException">
		/// if setInput () or deflate () were already called or another dictionary was already set.
		/// </exception>
		public void SetDictionary(byte[] dict, int offset, int length)
		{
			if (state != INIT_STATE) 
			{
				throw new InvalidOperationException();
			}
			
			state = SETDICT_STATE;
			engine.SetDictionary(dict, offset, length);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -