public static bool BrotliEncoderCompressStream( IntPtr state, BrotliEncoderOperation operation, ref UInt32 availableIn, ref IntPtr nextIn, ref UInt32 availableOut, ref IntPtr nextOut, out UInt32 totalOut) { if (USE_X86) { return(Brolib32.BrotliEncoderCompressStream( state, operation, ref availableIn, ref nextIn, ref availableOut, ref nextOut, out totalOut)); } UInt64 availableInL = availableIn; UInt64 availableOutL = availableOut; UInt64 totalOutL = 0; bool result = Brolib64.BrotliEncoderCompressStream( state, operation, ref availableInL, ref nextIn, ref availableOutL, ref nextOut, out totalOutL); availableIn = (UInt32)availableInL; availableOut = (UInt32)availableOutL; totalOut = (UInt32)totalOutL; return(result); }
protected override void FlushBrotliStream(bool finished) { if (!(this._state == IntPtr.Zero) && !Brolib.BrotliEncoderIsFinished(this._state)) { BrotliEncoderOperation op = finished ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Flush; uint totalOut = 0; while (Brolib.BrotliEncoderCompressStream(this._state, op, ref this._availableIn, ref this._ptrNextInput, ref this._availableOut, ref this._ptrNextOutput, out totalOut)) { bool flag = this._availableOut != 65536U; if (flag) { int num = 65536 - (int)this._availableOut; Marshal.Copy(this._ptrOutputBuffer, this._managedBuffer, 0, num); if (this.written) { this._stream.Write(this._managedBuffer, 0, num); } this._availableOut = 65536U; this._ptrNextOutput = this._ptrOutputBuffer; } if (Brolib.BrotliEncoderIsFinished(this._state) || !flag) { return; } } throw new BrotliException("Unable to finish encode stream"); } }
public static OperationStatus FlushEncoder(ReadOnlySpan <byte> source, Span <byte> destination, out int bytesConsumed, out int bytesWritten, ref State state, bool isFinished = true) { EnsureInitialized(ref state, true); BrotliEncoderOperation operation = isFinished ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Flush; bytesWritten = destination.Length; bytesConsumed = 0; if (state.BrotliNativeState == IntPtr.Zero) { return(OperationStatus.InvalidData); } if (BrotliNative.BrotliEncoderIsFinished(state.BrotliNativeState)) { return(OperationStatus.Done); } unsafe { IntPtr bufIn, bufOut; fixed(byte *inBytes = &MemoryMarshal.GetReference(source)) fixed(byte *outBytes = &MemoryMarshal.GetReference(destination)) { bufIn = new IntPtr(inBytes); bufOut = new IntPtr(outBytes); nuint availableOutput = (nuint)destination.Length; nuint consumed = (nuint)source.Length; if (!BrotliNative.BrotliEncoderCompressStream(state.BrotliNativeState, operation, ref consumed, ref bufIn, ref availableOutput, ref bufOut, out nuint totalOut)) { return(OperationStatus.InvalidData); } bytesConsumed = (int)consumed; bytesWritten = (int)availableOutput; } bytesWritten = destination.Length - bytesWritten; if (bytesWritten > 0) { if (BrotliNative.BrotliEncoderIsFinished(state.BrotliNativeState)) { return(OperationStatus.Done); } else { return(OperationStatus.DestinationTooSmall); } } } return(OperationStatus.Done); }
protected virtual void FlushBrotliStream(Boolean finished) { //test if the resource has been freed if (_state == IntPtr.Zero) { return; } if (Brolib.BrotliEncoderIsFinished(_state)) { return; } BrotliEncoderOperation op = finished ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Flush; UInt32 totalOut = 0; while (true) { var compressOK = Brolib.BrotliEncoderCompressStream(_state, op, ref _availableIn, ref _ptrNextInput, ref _availableOut, ref _ptrNextOutput, out totalOut); if (!compressOK) { throw new BrotliException("Unable to finish encode stream"); } var extraData = _availableOut != BufferSize; if (extraData) { var bytesWrote = (int)(BufferSize - _availableOut); if (_written) { Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, bytesWrote); _stream.Write(_managedBuffer, 0, bytesWrote); } _availableOut = BufferSize; _ptrNextOutput = _ptrOutputBuffer; } if (Brolib.BrotliEncoderIsFinished(_state)) { break; } if (!extraData) { break; } } }
protected virtual void FlushEncoder(bool finished) { if (_encoder.State == IntPtr.Zero) { return; } if (BrotliNative.BrotliEncoderIsFinished(_encoder.State)) { return; } BrotliEncoderOperation op = finished ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Flush; nuint totalOut = 0; while (true) { if (!BrotliNative.BrotliEncoderCompressStream(_encoder.State, op, ref _availableInput, ref _nextInput, ref _availableOutput, ref _nextOutput, out totalOut)) { throw new System.IO.IOException(BrotliEx.unableEncode); } var extraData = (nuint)_availableOutput != (nuint)_bufferSize; if (extraData) { var bytesWrote = (int)((nuint)_bufferSize - (nuint)_availableOutput); Byte[] buf = new Byte[bytesWrote]; Marshal.Copy(_bufferOutput, buf, 0, bytesWrote); _stream.Write(buf, 0, bytesWrote); _availableOutput = (nuint)_bufferSize; _nextOutput = _bufferOutput; } if (BrotliNative.BrotliEncoderIsFinished(_encoder.State)) { break; } if (!extraData) { break; } } }
public static bool BrotliEncoderCompressStream( IntPtr state, BrotliEncoderOperation op, ref IntPtr availableIn, ref IntPtr nextIn, ref IntPtr availableOut, ref IntPtr nextOut, out nuint totalOut) { return(Interop.Brotli.BrotliEncoderCompressStream(state, op, ref availableIn, ref nextIn, ref availableOut, ref nextOut, out totalOut)); }
internal static unsafe partial BOOL BrotliEncoderCompressStream( SafeBrotliEncoderHandle state, BrotliEncoderOperation op, ref nuint availableIn, byte **nextIn, ref nuint availableOut, byte **nextOut, out nuint totalOut);
internal static extern bool BrotliEncoderCompressStream( IntPtr state, BrotliEncoderOperation op, ref nuint availableIn, ref IntPtr nextIn, ref nuint availableOut, ref IntPtr nextOut, out nuint totalOut);
internal static extern unsafe bool BrotliEncoderCompressStream( SafeBrotliEncoderHandle state, BrotliEncoderOperation op, ref size_t availableIn, byte **nextIn, ref size_t availableOut, byte **nextOut, out size_t totalOut);
internal static unsafe bool BrotliEncoderCompressStream( SafeBrotliEncoderHandle state, BrotliEncoderOperation op, ref size_t availableIn, byte **nextIn, ref size_t availableOut, byte **nextOut, out size_t totalOut) => throw new PlatformNotSupportedException();
internal OperationStatus Compress(ReadOnlySpan <byte> source, Span <byte> destination, out int bytesConsumed, out int bytesWritten, BrotliEncoderOperation operation) { EnsureInitialized(); Debug.Assert(_state != null); bytesWritten = 0; bytesConsumed = 0; nuint availableOutput = (nuint)destination.Length; nuint availableInput = (nuint)source.Length; unsafe { // We can freely cast between int and nuint (.NET size_t equivalent) for two reasons: // 1. Interop Brotli functions will always return an availableInput/Output value lower or equal to the one passed to the function // 2. Span's have a maximum length of the int boundary. while ((int)availableOutput > 0) { fixed(byte *inBytes = &MemoryMarshal.GetReference(source)) fixed(byte *outBytes = &MemoryMarshal.GetReference(destination)) { if (Interop.Brotli.BrotliEncoderCompressStream(_state, operation, ref availableInput, &inBytes, ref availableOutput, &outBytes, out _) == Interop.BOOL.FALSE) { return(OperationStatus.InvalidData); } Debug.Assert(availableInput <= (nuint)source.Length); Debug.Assert(availableOutput <= (nuint)destination.Length); bytesConsumed += source.Length - (int)availableInput; bytesWritten += destination.Length - (int)availableOutput; // no bytes written, no remaining input to give to the encoder, and no output in need of retrieving means we are Done if ((int)availableOutput == destination.Length && Interop.Brotli.BrotliEncoderHasMoreOutput(_state) == Interop.BOOL.FALSE && availableInput == 0) { return(OperationStatus.Done); } source = source.Slice(source.Length - (int)availableInput); destination = destination.Slice(destination.Length - (int)availableOutput); } } return(OperationStatus.DestinationTooSmall); } }