Files
SabreTools/SabreTools.Library/Tools/SeparatedValueWriter.cs
2020-06-13 21:24:47 -07:00

144 lines
4.0 KiB
C#

using System;
using System.IO;
using System.Text;
namespace SabreTools.Library.Tools
{
public class SeparatedValueWriter : IDisposable
{
/// <summary>
/// Internal stream writer for outputting
/// </summary>
private StreamWriter sw;
/// <summary>
/// Internal value if we've written a header before
/// </summary>
private bool header = false;
/// <summary>
/// Internal value if we've written our first line before
/// </summary>
private bool firstRow = false;
/// <summary>
/// Internal value to say how many fields should be written
/// </summary>
private int fields = -1;
/// <summary>
/// Set if values should be wrapped in quotes
/// </summary>
public bool Quotes { get; set; } = true;
/// <summary>
/// Set what string should be used as a separator
/// </summary>
public string Separator { get; set; } = ",";
/// <summary>
/// Set if field count should be verified from the first row
/// </summary>
public bool VerifyFieldCount { get; set; } = true;
/// <summary>
/// Constructor for writing to a file
/// </summary>
public SeparatedValueWriter(string filename)
{
sw = new StreamWriter(filename);
}
/// <summary>
/// Consturctor for writing to a stream
/// </summary>
public SeparatedValueWriter(Stream stream, Encoding encoding)
{
sw = new StreamWriter(stream, encoding);
}
/// <summary>
/// Write a header row
/// </summary>
public void WriteHeader(string[] headers)
{
// If we haven't written anything out, we can write headers
if (!header && !firstRow)
WriteValues(headers);
header = true;
}
/// <summary>
/// Write a value row
/// </summary>
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();
}
/// <summary>
/// Dispose of the underlying writer
/// </summary>
public void Dispose()
{
sw.Dispose();
}
}
}