protected virtual void FlushEncoder(Boolean finished) { if (_encoder.State == IntPtr.Zero) { return; } if (BrotliNative.BrotliEncoderIsFinished(_encoder.State)) { return; } BrotliNative.BrotliEncoderOperation op = finished ? BrotliNative.BrotliEncoderOperation.Finish : BrotliNative.BrotliEncoderOperation.Flush; UInt32 totalOut = 0; while (true) { var compressOK = BrotliNative.BrotliEncoderCompressStream(_encoder.State, op, ref AvailIn, ref NextIn, ref AvailOut, ref NextOut, out totalOut); if (!compressOK) { throw new Exception(); // unable encode } var extraData = (nuint)AvailOut != BufferSize; if (extraData) { var bytesWrote = (int)(BufferSize - (nuint)AvailOut); Byte[] buf = new Byte[bytesWrote]; Marshal.Copy(BufferOut, buf, 0, bytesWrote); _stream.Write(buf, 0, bytesWrote); AvailOut = (IntPtr)BufferSize; NextOut = BufferOut; } if (BrotliNative.BrotliEncoderIsFinished(_encoder.State)) { break; } if (!extraData) { break; } } }
internal static extern bool BrotliEncoderCompressStream( IntPtr state, BrotliNative.BrotliEncoderOperation op, ref nuint availableIn, ref IntPtr nextIn, ref nuint availableOut, ref IntPtr nextOut, out nuint totalOut);