WriteOnlyStream refactorization

This commit is contained in:
Marcin Ziąbek
2022-01-24 00:34:27 +01:00
parent b5839d3989
commit 946fe91a98
5 changed files with 62 additions and 57 deletions
+4 -2
View File
@@ -18,14 +18,16 @@ namespace QuestPDF.Drawing
internal static void GeneratePdf(Stream stream, IDocument document)
{
var metadata = document.GetMetadata();
var canvas = new PdfCanvas(stream, metadata);
var writeOnlyStream = new WriteOnlyStream(stream);
var canvas = new PdfCanvas(writeOnlyStream, metadata);
RenderDocument(canvas, document);
}
internal static void GenerateXps(Stream stream, IDocument document)
{
var metadata = document.GetMetadata();
var canvas = new XpsCanvas(stream, metadata);
var writeOnlyStream = new WriteOnlyStream(stream);
var canvas = new XpsCanvas(writeOnlyStream, metadata);
RenderDocument(canvas, document);
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace QuestPDF.Drawing
internal class PdfCanvas : SkiaDocumentCanvasBase
{
public PdfCanvas(Stream stream, DocumentMetadata documentMetadata)
: base(SKDocument.CreatePdf(new WriteStreamWrapper(stream), MapMetadata(documentMetadata)))
: base(SKDocument.CreatePdf(stream, MapMetadata(documentMetadata)))
{
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace QuestPDF.Drawing
internal class XpsCanvas : SkiaDocumentCanvasBase
{
public XpsCanvas(Stream stream, DocumentMetadata documentMetadata)
: base(SKDocument.CreateXps(new WriteStreamWrapper(stream), documentMetadata.RasterDpi))
: base(SKDocument.CreateXps(stream, documentMetadata.RasterDpi))
{
}
+56
View File
@@ -0,0 +1,56 @@
using System;
using System.IO;
namespace QuestPDF.Helpers
{
/// <summary>
/// SkiaSharp calls the Position property when generating target document file.
/// If the output stream does not support the Position property, the NullReferenceException is thrown.
/// This wrapper fixes this issue by providing cached Position value (always the end of the stream / current length).
/// Example stream affected: HttpContext.Response.Body
/// </summary>
internal class WriteOnlyStream : Stream
{
private readonly Stream InnerStream;
private long StreamLength { get; set; }
public WriteOnlyStream(Stream stream)
{
if (!stream.CanWrite)
throw new NotSupportedException("Stream cannot be written");
InnerStream = stream;
}
public override bool CanRead => false;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => StreamLength;
public override long Position
{
get => StreamLength;
set => throw new NotImplementedException();
}
public override void Flush() => InnerStream.Flush();
public override int Read(byte[] buffer, int offset, int count)
=> throw new NotImplementedException();
public override long Seek(long offset, SeekOrigin origin)
=> throw new NotImplementedException();
public override void SetLength(long value)
=> throw new NotImplementedException();
public override void Write(byte[] buffer, int offset, int count)
{
InnerStream.Write(buffer, offset, count);
StreamLength += count;
}
}
}
-53
View File
@@ -1,53 +0,0 @@
using System;
using System.IO;
namespace QuestPDF.Helpers
{
internal class WriteStreamWrapper : Stream
{
private readonly Stream _innerStream;
private long _length;
public WriteStreamWrapper(Stream stream)
{
if (!stream.CanWrite)
{
throw new NotSupportedException("Stream cannot be written");
}
_innerStream = stream;
}
public override bool CanRead => false;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => _length;
public override long Position {
get => _length;
set => throw new NotImplementedException();
}
public override void Flush()
=> _innerStream.Flush();
public override int Read(byte[] buffer, int offset, int count)
=> throw new NotImplementedException();
public override long Seek(long offset, SeekOrigin origin)
=> throw new NotImplementedException();
public override void SetLength(long value)
=> throw new NotImplementedException();
public override void Write(byte[] buffer, int offset, int count)
{
_innerStream.Write(buffer, offset, count);
_length += count;
}
}
}