using ReportGenerator.Generator.Interface;
using System.Text;
namespace ReportGenerator.Generator.Abstract;
public abstract class StreamWriterBase : IStreamWriter
{
private bool _isOpen;
private bool _isClosed;
///
/// Underlying
///
private Stream Stream { get; }
///
/// Internal for generating the output
///
protected TextWriter Writer { get; }
///
/// Constructor; Configures the
/// to write to the memory
///
protected StreamWriterBase() : this(new MemoryStream()) { }
///
protected StreamWriterBase(Stream stream) : this(stream, Encoding.UTF8) { }
///
/// Constructor; Configures the
/// to write to the specified
///
/// The to write to
/// Text of the written data
protected StreamWriterBase(Stream stream, Encoding encoding)
{
Stream = stream;
Writer = new StreamWriter(stream, encoding);
}
#region Control
public void Open()
{
if (_isOpen)
{
throw new InvalidOperationException($"{GetType()} has already been opened");
}
if (_isClosed)
{
throw new InvalidOperationException($"Cannot call open on a closed {GetType()}");
}
_isOpen = true;
OnOpen();
}
public void Close()
{
if (_isClosed)
{
throw new InvalidOperationException($"{GetType()} has already been closed");
}
if (!_isOpen)
{
throw new InvalidOperationException($"{GetType()} has never been opened");
}
_isClosed = true;
OnClose();
Writer.Flush();
}
///
/// Called once the internal writer has been initialized
/// and the is ready for writing
///
protected virtual void OnOpen() { }
///
/// Called once the document is about to be closed
///
protected virtual void OnClose() { }
#endregion
#region Reading
///
public StreamReader Read()
{
Writer.Flush();
Stream.Seek(0, SeekOrigin.Begin);
return new StreamReader(Stream, Writer.Encoding);
}
#endregion
#region Writing
public IStreamWriter Write(IStreamWriter writer)
{
using var reader = writer.Read();
return Write(reader);
}
public IStreamWriter Write(StreamReader reader)
{
int bytesRead;
char[] buffer = new char[4096];
while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0)
{
Writer.Write(buffer, 0, bytesRead);
}
return this;
}
public IStreamWriter Write(string? text = default)
{
Writer.Write(text);
return this;
}
public IStreamWriter WriteLine(string? text = default)
{
Writer.WriteLine(text);
return this;
}
///
/// Creates and configures the using the given functions
///
/// Type of the
/// Function used to generate the
/// Function used to configure the
///
public IStreamWriter Write(Func makeFunc, Action configFunc)
where T : IStreamWriter
{
using var writer = makeFunc();
writer.Open();
configFunc(writer);
writer.Close();
Write(writer);
return this;
}
#endregion
#region IDisposable
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
try
{
// Close document
Close();
}
catch (InvalidOperationException)
{
// ignore
}
finally
{
// Dispose stream
Stream.Dispose();
}
}
}
///
public void Dispose()
{
if (_disposed)
{
return;
}
_disposed = true;
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}