public void FlushStoredBlock(byte[] stored, int stored_offset, int stored_len, bool lastBlock) { // if (DeflaterConstants.DEBUGGING) { // //Console.WriteLine("Flushing stored block "+ stored_len); // } pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3); pending.AlignToByte(); pending.WriteShort(stored_len); pending.WriteShort(~stored_len); pending.WriteBlock(stored, stored_offset, stored_len); Reset(); }
/// <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); }