using iText.Kernel.Pdf; #if NETFRAMEWORK using System.IO; using System; using System.Threading.Tasks; #endif namespace EnvelopeGenerator.PdfEditor { public class Edit : IDisposable, IAsyncDisposable where TInputStream : Stream where TOutputStream : Stream { private readonly PdfDocument _doc; private readonly TInputStream _inputStream; private readonly TOutputStream _outputStream; private readonly PdfReader _reader; private readonly PdfWriter _writer; private bool _disposed = false; public Edit(TInputStream inputStream, TOutputStream outputStream) { _inputStream = inputStream; _outputStream = outputStream; _reader = new PdfReader(inputStream); _writer = new PdfWriter(outputStream); _doc = new PdfDocument(_reader, _writer); } public static Edit OnByte(byte[] documentBytes) { return new Edit(new MemoryStream(documentBytes), new MemoryStream()); } // Finalizer ~Edit() { // If Dispose is not called, clean up unmanaged resources Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (_disposed) return; if (disposing) { // Managed resources _doc?.Close(); _inputStream?.Dispose(); _outputStream?.Dispose(); } else { // When called by the finalizer, clean up only unmanaged resources // Unmanaged resources such as PdfDocument, PdfReader, and PdfWriter are already IDisposable; we close them here try { _doc?.Close(); } catch { } try { _inputStream?.Dispose(); } catch { } try { _outputStream?.Dispose(); } catch { } } _disposed = true; } public async ValueTask DisposeAsync() { if (_disposed) return; _doc?.Close(); if (_inputStream is IAsyncDisposable asyncInput) await asyncInput.DisposeAsync(); else _inputStream.Dispose(); if (_outputStream is IAsyncDisposable asyncOutput) await asyncOutput.DisposeAsync(); else _outputStream?.Dispose(); _disposed = true; GC.SuppressFinalize(this); } } }