private void WriteCore(byte[] buffer, int offset, int count, Brotli.BrotliEncoderOperation operation) { bool flush = operation == Brotli.BrotliEncoderOperation.BROTLI_OPERATION_FLUSH || operation == Brotli.BrotliEncoderOperation.BROTLI_OPERATION_FINISH; byte[] out_buf = new byte[0x1FFFE]; size_t available_in = count, available_out = out_buf.Length; fixed (byte* out_buf_ptr = out_buf) fixed (byte* buf_ptr = buffer) { byte* next_in = buf_ptr + offset; byte* next_out = out_buf_ptr; while ((!flush && available_in > 0) || flush) { if (!Brotli.BrotliEncoderCompressStream(ref _encoderState, operation, &available_in, &next_in, &available_out, &next_out, null)) { throw new InvalidDataException("Compression failed"); } bool hasData = available_out != out_buf.Length; if (hasData) { int out_size = (int)(out_buf.Length - available_out); _stream.Write(out_buf, 0, out_size); available_out = out_buf.Length; next_out = out_buf_ptr; } if (Brotli.BrotliEncoderIsFinished(ref _encoderState)) break; if (!hasData && flush) break; } } }
private void FlushCompress(bool finish) { if (_mode != CompressionMode.Compress) return; if (Brotli.BrotliEncoderIsFinished(ref _encoderState)) return; var op = finish ? Brotli.BrotliEncoderOperation.BROTLI_OPERATION_FINISH : Brotli.BrotliEncoderOperation.BROTLI_OPERATION_FLUSH; byte[] buffer = new byte[0]; WriteCore(buffer, 0, 0, op); }