예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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);
        }