using System;
using System.IO;
using System.Text;
namespace SabreTools.Library.Tools
{
public class SeparatedValueWriter : IDisposable
{
///
/// Internal stream writer for outputting
///
private StreamWriter sw;
///
/// Internal value if we've written a header before
///
private bool header = false;
///
/// Internal value if we've written our first line before
///
private bool firstRow = false;
///
/// Internal value to say how many fields should be written
///
private int fields = -1;
///
/// Set if values should be wrapped in quotes
///
public bool Quotes { get; set; } = true;
///
/// Set what string should be used as a separator
///
public string Separator { get; set; } = ",";
///
/// Set if field count should be verified from the first row
///
public bool VerifyFieldCount { get; set; } = true;
///
/// Constructor for writing to a file
///
public SeparatedValueWriter(string filename)
{
sw = new StreamWriter(filename);
}
///
/// Consturctor for writing to a stream
///
public SeparatedValueWriter(Stream stream, Encoding encoding)
{
sw = new StreamWriter(stream, encoding);
}
///
/// Write a header row
///
public void WriteHeader(string[] headers)
{
// If we haven't written anything out, we can write headers
if (!header && !firstRow)
WriteValues(headers);
header = true;
}
///
/// Write a value row
///
public void WriteValues(object[] values)
{
// If the writer can't be used, we error
if (sw == null || !sw.BaseStream.CanWrite)
throw new ArgumentException(nameof(sw));
// If the separator character is invalid, we error
if (string.IsNullOrEmpty(Separator))
throw new ArgumentException(nameof(Separator));
// If we have the first row, set the bool and the field count
if (!firstRow)
{
firstRow = true;
if (VerifyFieldCount && fields == -1)
fields = values.Length;
}
// Get the number of fields to write out
int fieldCount = values.Length;
if (VerifyFieldCount)
fieldCount = Math.Min(fieldCount, fields);
// Iterate over the fields, writing out each
bool firstField = true;
for (int i = 0; i < fieldCount; i++)
{
var value = values[i];
if (!firstField)
sw.Write(Separator);
if (Quotes)
sw.Write("\"");
sw.Write(value.ToString());
if (Quotes)
sw.Write("\"");
firstField = false;
}
// If we need to pad out the number of fields, add empties
if (VerifyFieldCount && values.Length < fields)
{
for (int i = 0; i < fields - values.Length; i++)
{
sw.Write(Separator);
if (Quotes)
sw.Write("\"\"");
}
}
// Add a newline
sw.WriteLine();
// Flush the buffer
sw.Flush();
}
///
/// Dispose of the underlying writer
///
public void Dispose()
{
sw.Dispose();
}
}
}