예제 #1
0
        public static async Task CopyToAsync(this IPipelineReader input, IPipelineWriter output)
        {
            while (true)
            {
                var result = await input.ReadAsync();

                var inputBuffer = result.Buffer;

                var fin = result.IsCompleted;

                try
                {
                    if (inputBuffer.IsEmpty && fin)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }
            }
        }
예제 #2
0
        public static Task WriteAsync(this IPipelineWriter output, Span <byte> source)
        {
            var writeBuffer = output.Alloc();

            writeBuffer.Write(source);
            return(writeBuffer.FlushAsync());
        }
예제 #3
0
 internal PipelineBuilderBase(Source[] source, HostContext hostContext)
 {
     Option        = new PSDocumentOption();
     Source        = source;
     Writer        = new HostPipelineWriter(hostContext);
     ShouldProcess = hostContext == null ? EmptyShouldProcess : hostContext.ShouldProcess;
     OutputVisitor = (o, enumerate) => WriteToString(o, enumerate, Writer);
 }
예제 #4
0
 public HttpConnection(IHttpApplication <TContext> application, IPipelineReader input, IPipelineWriter output)
 {
     _application  = application;
     _input        = input;
     _output       = output;
     _requestBody  = new HttpRequestStream <TContext>(this);
     _responseBody = new HttpResponseStream <TContext>(this);
 }
예제 #5
0
        public static void WriteError(this IPipelineWriter writer, Exception exception, string errorId, ErrorCategory errorCategory, object targetObject)
        {
            if (writer == null)
            {
                return;
            }

            writer.WriteError(new ErrorRecord(exception, errorId, errorCategory, targetObject));
        }
예제 #6
0
        public static void Debug(this IPipelineWriter writer, string message)
        {
            if (writer == null)
            {
                return;
            }

            writer.WriteDebug(new DebugRecord(message));
        }
예제 #7
0
        public static void WarnSourcePathNotFound(this IPipelineWriter writer)
        {
            if (writer == null)
            {
                return;
            }

            writer.WriteWarning(PSDocsResources.SourceNotFound);
        }
예제 #8
0
        public static void WarnTitleEmpty(this IPipelineWriter writer)
        {
            if (writer == null)
            {
                return;
            }

            writer.WriteWarning(PSDocsResources.TitleEmpty);
        }
예제 #9
0
 protected PathBuilder(IPipelineWriter logger, string basePath, string searchPattern, PathFilter filter)
 {
     _Logger               = logger;
     _Files                = new List <InputFileInfo>();
     _Paths                = new HashSet <string>();
     _BasePath             = NormalizePath(PSDocumentOption.GetRootedBasePath(basePath));
     _DefaultSearchPattern = searchPattern;
     _GlobalFilter         = filter;
 }
예제 #10
0
 public PipelineContext(PSDocumentOption option, IPipelineWriter writer, Action <IDocumentResult, bool> _Output, InstanceNameBinder instanceNameBinder)
 {
     Option             = option;
     LanguageMode       = option.Execution.LanguageMode.GetValueOrDefault(ExecutionOption.Default.LanguageMode.Value);
     Filter             = DocumentFilter.Create(Option.Document.Include, Option.Document.Tag);
     Writer             = writer;
     InstanceNameBinder = instanceNameBinder;
     _OutputVisitor     = _Output;
 }
예제 #11
0
        public IPipelineWriter CreateWriter(IPipelineWriter writer, Func<IPipelineReader, IPipelineWriter, Task> consume)
        {
            var newWriter = new PipelineReaderWriter(_pool);

            consume(newWriter, writer).ContinueWith(t =>
            {
            });

            return newWriter;
        }
예제 #12
0
        public IPipelineWriter CreateWriter(IPipelineWriter writer, Func <IPipelineReader, IPipelineWriter, Task> consume)
        {
            var newWriter = new PipelineReaderWriter(_pool);

            consume(newWriter, writer).ContinueWith(t =>
            {
            });

            return(newWriter);
        }
예제 #13
0
        public IPipelineWriter CreateWriter(IPipelineWriter writer, Func <IPipelineReader, IPipelineWriter, Task> consume)
        {
            var pipe = new Pipe(_pool);

            consume(pipe, writer).ContinueWith(t =>
            {
            });

            return(pipe);
        }
예제 #14
0
 public PipelineContext(OptionContext option, PipelineStream stream, IPipelineWriter writer, Action <IDocumentResult, bool> _Output, InstanceNameBinder instanceNameBinder, string[] convention)
 {
     Option             = option;
     LanguageMode       = option.Execution.LanguageMode.GetValueOrDefault(ExecutionOption.Default.LanguageMode.Value);
     Filter             = DocumentFilter.Create(option.Document.Include, option.Document.Tag);
     Stream             = stream ?? new PipelineStream(null, null);
     Writer             = writer;
     InstanceNameBinder = instanceNameBinder;
     _OutputVisitor     = _Output;
     Convention         = convention;
     Selector           = new Dictionary <string, SelectorVisitor>();
 }
예제 #15
0
        public static void ErrorInvariantCulture(this IPipelineWriter writer)
        {
            if (writer == null)
            {
                return;
            }

            writer.WriteError(new ErrorRecord(
                                  exception: new PipelineBuilderException(PSDocsResources.InvariantCulture),
                                  errorId: "PSDocs.PipelineBuilder.InvariantCulture",
                                  errorCategory: ErrorCategory.InvalidOperation,
                                  null
                                  ));
        }
예제 #16
0
        public static void WriteError(this IPipelineWriter writer, ParseError error)
        {
            if (writer == null)
            {
                return;
            }

            var record = new ErrorRecord
                         (
                exception: new ParseException(message: error.Message, errorId: error.ErrorId),
                errorId: error.ErrorId,
                errorCategory: ErrorCategory.InvalidOperation,
                targetObject: null
                         );

            writer.WriteError(record);
        }
        private static async Task CopyCompletedAsync(IPipelineReader input, IPipelineWriter output)
        {
            var result = await input.ReadAsync();

            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();

                inputBuffer = result.Buffer;
            }
        }
        private static async Task CopyCompletedAsync(IPipelineReader input, IPipelineWriter output)
        {
            var result = await input.ReadAsync();
            var inputBuffer = result.Buffer;

            while (true)
            {
                try
                {
                    if (inputBuffer.IsEmpty && result.IsCompleted)
                    {
                        return;
                    }

                    var buffer = output.Alloc();

                    buffer.Append(inputBuffer);

                    await buffer.FlushAsync();
                }
                finally
                {
                    input.Advance(inputBuffer.End);
                }

                var awaiter = input.ReadAsync();

                if (!awaiter.IsCompleted)
                {
                    // No more data
                    break;
                }

                result = await input.ReadAsync();
                inputBuffer = result.Buffer;
            }
        }
예제 #19
0
 protected PipelineWriter(IHostContext hostContext, IPipelineWriter inner)
     : base(hostContext)
 {
     _Inner = inner;
 }
예제 #20
0
 /// <summary>
 /// Copies the content of a <see cref="Stream"/> into a <see cref="IPipelineWriter"/>.
 /// </summary>
 /// <param name="stream"></param>
 /// <param name="writer"></param>
 /// <returns></returns>
 public static Task CopyToAsync(this Stream stream, IPipelineWriter writer)
 {
     return stream.CopyToAsync(new PipelineWriterStream(writer));
 }
예제 #21
0
 public PipelineWriterStream(IPipelineWriter writer)
 {
     _writer = writer;
 }
 public static IPipelineWriter CreateGZipCompressWriter(this PipelineFactory factory, IPipelineWriter writer, CompressionLevel compressionLevel)
 {
     var deflater = new WritableDeflateTransform(compressionLevel, ZLibNative.GZip_DefaultWindowBits);
     return factory.CreateWriter(writer, deflater.Execute);
 }
예제 #23
0
        public async Task HandleHandshakeMessage(HandshakeType handshakeMessageType, ReadableBuffer buffer, IPipelineWriter pipe)
        {
            switch (State)
            {
            case StateType.WaitServerHello:
                if (handshakeMessageType == HandshakeType.server_hello)
                {
                    Hello.ReadServerHello(buffer, this);
                    GenerateHandshakeKeys();
                    State = StateType.WaitEncryptedExtensions;
                    return;
                }
                break;

            case StateType.WaitEncryptedExtensions:
                if (handshakeMessageType == HandshakeType.encrypted_extensions)
                {
                    HandshakeContext(buffer);
                    State = StateType.WaitServerVerification;
                    return;
                }
                break;

            case StateType.WaitServerVerification:
                if (handshakeMessageType == HandshakeType.certificate)
                {
                    Handshake.Certificates.ReadCertificates(buffer, Listener);
                    HandshakeContext(buffer);
                    return;
                }
                if (handshakeMessageType == HandshakeType.certificate_verify)
                {
                    HandshakeContext(buffer);
                    State = StateType.WaitServerFinished;
                    return;
                }
                break;

            case StateType.WaitServerFinished:
                if (handshakeMessageType == HandshakeType.finished)
                {
                    HandshakeContext(buffer);
                    var hash = new byte[HandshakeHash.HashSize];
                    HandshakeHash.InterimHash(hash);
                    var writer = pipe.Alloc();
                    ServerHandshakeTls13.ServerFinished(ref writer, this, KeySchedule.GenerateClientFinishedKey());
                    _dataForCurrentScheduleSent.Reset();
                    await writer.FlushAsync();

                    await _dataForCurrentScheduleSent;
                    GenerateApplicationKeys(hash);
                    KeySchedule.GenerateResumptionSecret();
                    HandshakeHash.Dispose();
                    HandshakeHash = null;
                    State         = StateType.HandshakeComplete;
                    return;
                }
                break;

            case StateType.HandshakeComplete:
                if (handshakeMessageType == HandshakeType.new_session_ticket)
                {
                    Listener.ResumptionProvider.RegisterSessionTicket(buffer);
                    return;
                }
                break;
            }
            Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.unexpected_message, "");
        }
예제 #24
0
        private static void WriteToFile(IDocumentResult result, PSDocumentOption option, IPipelineWriter writer, ShouldProcess shouldProcess)
        {
            // Calculate paths
            var fileName   = string.Concat(result.InstanceName, result.Extension);
            var outputPath = PSDocumentOption.GetRootedPath(result.OutputPath);
            var filePath   = Path.Combine(outputPath, fileName);
            var parentPath = Directory.GetParent(filePath);

            if (!parentPath.Exists && shouldProcess(target: parentPath.FullName, action: PSDocsResources.ShouldCreatePath))
            {
                Directory.CreateDirectory(path: parentPath.FullName);
            }

            if (shouldProcess(target: outputPath, action: PSDocsResources.ShouldWriteFile))
            {
                var encoding = GetEncoding(option.Markdown.Encoding.Value);
                File.WriteAllText(filePath, result.ToString(), encoding);

                // Write file info instead
                var fileInfo = new FileInfo(filePath);
                writer.WriteObject(fileInfo, false);
            }
        }
예제 #25
0
        public override async Task HandleHandshakeMessage(HandshakeType handshakeMessageType, ReadableBuffer buffer, IPipelineWriter pipe)
        {
            WritableBuffer writer;

            switch (State)
            {
            case StateType.None:
                if (handshakeMessageType != HandshakeType.client_hello)
                {
                    Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.unexpected_message, "Tls 12 didnt get a client hello");
                }
                Hello.ReadClientHelloTls12(buffer, this);
                if (CipherSuite == null)
                {
                    //Couldn't agree a set of ciphers
                    Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "Could not agree on a cipher suite during reading client hello");
                }
                this.StartHandshakeHash(buffer);
                //Write server hello
                _state = StateType.SendServerHello;
                writer = pipe.Alloc();
                this.WriteHandshake(ref writer, HandshakeType.server_hello, Hello.SendServerHello12);
                this.WriteHandshake(ref writer, HandshakeType.certificate, ServerHandshakeTls12.SendCertificates);
                if (CipherSuite.ExchangeType == KeyExchangeType.Ecdhe || CipherSuite.ExchangeType == KeyExchangeType.Dhe)
                {
                    this.WriteHandshake(ref writer, HandshakeType.server_key_exchange, ServerHandshakeTls12.SendKeyExchange);
                }
                await writer.FlushAsync();

                break;

            default:
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.unexpected_message, $"Not in any known state {State} that we expected a handshake messge from {handshakeMessageType}");
                break;
            }
        }
            public async Task Execute(IPipelineReader reader, IPipelineWriter writer)
            {
                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var memory       = inputBuffer.First;

                    unsafe
                    {
                        // TODO: Pin pointer if not pinned
                        void *inPointer;
                        if (memory.TryGetPointer(out inPointer))
                        {
                            _deflater.SetInput((IntPtr)inPointer, memory.Length);
                        }
                        else
                        {
                            throw new InvalidOperationException("Pointer needs to be pinned");
                        }
                    }

                    while (!_deflater.NeedsInput())
                    {
                        unsafe
                        {
                            void *outPointer;
                            writerBuffer.Ensure();
                            if (writerBuffer.Memory.TryGetPointer(out outPointer))
                            {
                                int written = _deflater.ReadDeflateOutput((IntPtr)outPointer, writerBuffer.Memory.Length);
                                writerBuffer.Advance(written);
                            }
                            else
                            {
                                throw new InvalidOperationException("Pointer needs to be pinned");
                            }
                        }
                    }

                    var consumed = memory.Length - _deflater.AvailableInput;

                    inputBuffer = inputBuffer.Slice(0, consumed);

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                bool flushed = false;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        void *pointer;
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Memory;
                        if (memory.TryGetPointer(out pointer))
                        {
                            int compressedBytes;
                            flushed = _deflater.Flush((IntPtr)pointer, memory.Length, out compressedBytes);
                            writerBuffer.Advance(compressedBytes);
                        }
                        else
                        {
                            throw new InvalidOperationException("Pointer needs to be pinned");
                        }
                    }

                    await writerBuffer.FlushAsync();
                }while (flushed);

                bool finished = false;

                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        void *pointer;
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Memory;
                        if (memory.TryGetPointer(out pointer))
                        {
                            int compressedBytes;
                            finished = _deflater.Finish((IntPtr)pointer, memory.Length, out compressedBytes);
                            writerBuffer.Advance(compressedBytes);
                        }
                    }

                    await writerBuffer.FlushAsync();
                }while (!finished);

                reader.Complete();

                writer.Complete();

                _deflater.Dispose();
            }
예제 #27
0
 /// <summary>
 /// Copies the content of a <see cref="Stream"/> into a <see cref="IPipelineWriter"/>.
 /// </summary>
 /// <param name="stream"></param>
 /// <param name="writer"></param>
 /// <returns></returns>
 public static Task CopyToAsync(this Stream stream, IPipelineWriter writer)
 {
     return(stream.CopyToAsync(new PipelineWriterStream(writer)));
 }
            public async Task Execute(IPipelineReader reader, IPipelineWriter writer)
            {
                while (true)
                {
                    var result = await reader.ReadAsync();
                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var memory = inputBuffer.First;

                    unsafe
                    {
                        // TODO: Pin pointer if not pinned
                        void* inPointer;
                        if (memory.TryGetPointer(out inPointer))
                        {
                            _deflater.SetInput((IntPtr)inPointer, memory.Length);
                        }
                        else
                        {
                            throw new InvalidOperationException("Pointer needs to be pinned");
                        }
                    }

                    while (!_deflater.NeedsInput())
                    {
                        unsafe
                        {
                            void* outPointer;
                            writerBuffer.Ensure();
                            if (writerBuffer.Memory.TryGetPointer(out outPointer))
                            {
                                int written = _deflater.ReadDeflateOutput((IntPtr)outPointer, writerBuffer.Memory.Length);
                                writerBuffer.Advance(written);
                            }
                            else
                            {
                                throw new InvalidOperationException("Pointer needs to be pinned");
                            }
                        }
                    }

                    var consumed = memory.Length - _deflater.AvailableInput;

                    inputBuffer = inputBuffer.Slice(0, consumed);

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                bool flushed = false;
                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        void* pointer;
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Memory;
                        if (memory.TryGetPointer(out pointer))
                        {
                            int compressedBytes;
                            flushed = _deflater.Flush((IntPtr)pointer, memory.Length, out compressedBytes);
                            writerBuffer.Advance(compressedBytes);
                        }
                        else
                        {
                            throw new InvalidOperationException("Pointer needs to be pinned");
                        }
                    }

                    await writerBuffer.FlushAsync();
                }
                while (flushed);

                bool finished = false;
                do
                {
                    // Need to do more stuff here
                    var writerBuffer = writer.Alloc();

                    unsafe
                    {
                        void* pointer;
                        writerBuffer.Ensure();
                        var memory = writerBuffer.Memory;
                        if (memory.TryGetPointer(out pointer))
                        {
                            int compressedBytes;
                            finished = _deflater.Finish((IntPtr)pointer, memory.Length, out compressedBytes);
                            writerBuffer.Advance(compressedBytes);
                        }
                    }

                    await writerBuffer.FlushAsync();
                }
                while (!finished);

                reader.Complete();

                writer.Complete();

                _deflater.Dispose();
            }
예제 #29
0
 public PipelineWriterStream(IPipelineWriter writer)
 {
     _writer = writer;
 }
예제 #30
0
 internal SourcePipelineBuilder(HostContext hostContext)
 {
     _Source      = new List <Source>();
     _HostContext = hostContext;
     _Writer      = new HostPipelineWriter(hostContext);
 }
예제 #31
0
 protected BufferedPipelineWriter(IHostContext hostContext, IPipelineWriter inner)
     : base(hostContext, inner)
 {
     _Result = new List <T>();
 }
예제 #32
0
        private static void WriteToFile(IDocumentResult result, PSDocumentOption option, IPipelineWriter writer, ShouldProcess shouldProcess)
        {
            var rootedPath = PSDocumentOption.GetRootedPath(option.Output.Path);
            var filePath   = !string.IsNullOrEmpty(result.Culture) && option.Output?.Culture?.Length > 1 ?
                             Path.Combine(rootedPath, result.Culture, result.Name) : Path.Combine(rootedPath, result.Name);
            var parentPath = Directory.GetParent(filePath);

            if (!parentPath.Exists && shouldProcess(target: parentPath.FullName, action: PSDocsResources.ShouldCreatePath))
            {
                Directory.CreateDirectory(path: parentPath.FullName);
            }
            if (shouldProcess(target: rootedPath, action: PSDocsResources.ShouldWriteFile))
            {
                var encoding = GetEncoding(option.Markdown.Encoding.Value);
                File.WriteAllText(filePath, result.ToString(), encoding);

                // Write file info instead
                var fileInfo = new FileInfo(filePath);
                writer.WriteObject(fileInfo, false);
            }
        }
예제 #33
0
 public PipelineTextOutput(IPipelineWriter writer, EncodingData encoding)
 {
     _writer = writer;
     Encoding = encoding;
 }
예제 #34
0
 private static void WriteToString(IDocumentResult result, bool enumerate, IPipelineWriter writer)
 {
     writer.WriteObject(result.ToString(), enumerate);
 }
            public async Task Execute(IPipelineReader reader, IPipelineWriter writer)
            {
                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var memory       = inputBuffer.First;
                    if (memory.Length > 0)
                    {
                        unsafe
                        {
                            void *pointer;
                            if (memory.TryGetPointer(out pointer))
                            {
                                _inflater.SetInput((IntPtr)pointer, memory.Length);

                                void *writePointer;
                                writerBuffer.Ensure();
                                if (writerBuffer.Memory.TryGetPointer(out writePointer))
                                {
                                    int written = _inflater.Inflate((IntPtr)writePointer, writerBuffer.Memory.Length);
                                    writerBuffer.Advance(written);
                                }
                                else
                                {
                                    throw new InvalidOperationException("Pointer needs to be pinned");
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("Pointer needs to be pinned");
                            }

                            var consumed = memory.Length - _inflater.AvailableInput;

                            inputBuffer = inputBuffer.Slice(0, consumed);
                        }
                    }

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                reader.Complete();

                writer.Complete();

                _inflater.Dispose();
            }
            public async Task Execute(IPipelineReader reader, IPipelineWriter writer)
            {
                while (true)
                {
                    var result = await reader.ReadAsync();
                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.Advance(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer.Alloc();
                    var memory = inputBuffer.First;
                    if (memory.Length > 0)
                    {
                        unsafe
                        {
                            void* pointer;
                            if (memory.TryGetPointer(out pointer))
                            {
                                _inflater.SetInput((IntPtr)pointer, memory.Length);

                                void* writePointer;
                                writerBuffer.Ensure();
                                if (writerBuffer.Memory.TryGetPointer(out writePointer))
                                {
                                    int written = _inflater.Inflate((IntPtr)writePointer, writerBuffer.Memory.Length);
                                    writerBuffer.Advance(written);
                                }
                                else
                                {
                                    throw new InvalidOperationException("Pointer needs to be pinned");
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("Pointer needs to be pinned");
                            }

                            var consumed = memory.Length - _inflater.AvailableInput;

                            inputBuffer = inputBuffer.Slice(0, consumed);
                        }
                    }

                    reader.Advance(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                reader.Complete();

                writer.Complete();

                _inflater.Dispose();
            }
예제 #37
0
 public static PipelineTextOutput AsTextOutput(this IPipelineWriter writer, EncodingData formattingData)
 {
     return(new PipelineTextOutput(writer, formattingData));
 }
        public static IPipelineWriter CreateGZipCompressWriter(this PipelineFactory factory, IPipelineWriter writer, CompressionLevel compressionLevel)
        {
            var deflater = new WritableDeflateTransform(compressionLevel, ZLibNative.GZip_DefaultWindowBits);

            return(factory.CreateWriter(writer, deflater.Execute));
        }