📄 deflater.cs
字号:
/// </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 + -