Files
Common-VS2019/SacsStandardBase/Base/Data/SacsCsvHandler.cs
T
2021-05-05 15:36:28 +01:00

118 lines
3.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Base.Data
{
//=======================================================================
/// <summary>
/// Very basic CSV data handling.
/// <para>For more advanced CSV features, see SaCsvHelper in SacsWinOffice.</para>
/// </summary>
public static class SacsCsvHandler
{
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
public static String ToCsv (this IEnumerable<String> values, char fieldDelimiter = ',', char textDelimiter = '"')
{
String data = "";
int valueCount = 0;
foreach (String rawValue in values)
{
valueCount++;
String value = rawValue;
if (value.Contains(fieldDelimiter.ToString()) || value.Contains(textDelimiter.ToString()))
value = textDelimiter + value.Replace(textDelimiter.ToString(), textDelimiter.ToString() + textDelimiter.ToString()) + textDelimiter;
data += (valueCount > 1 ? fieldDelimiter.ToString() : "") + value;
}
return data;
}
//-------------------------------------------------------------------
/// <summary>
/// Extract comma delimited fields from data record.
/// <para>Fields starting with double quotes are terminated with the next single double quotes character.</para>
/// <para>Embedded double quotes pairs are treated as a single double quotes character.</para>
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static List<String> ParseCsvRecord (String data, char fieldDelimiter = ',', char textDelimiter = '"')
{
List<String> fields = new List<string>();
if (data == null) return fields;
// Parse control properties.
String currentField = "";
bool inTextField = false;
bool previousCharTextDelim = false;
// Parse the data.
foreach (char c in data)
{
if (inTextField)
{
if (c == textDelimiter)
{
// Text delimiter found.
if (!previousCharTextDelim)
{
// Make a note that a text delimiter has been found.
previousCharTextDelim = true;
continue;
}
else
{
// 2nd text delimiter found - add single text delimiter to field.
currentField += c;
previousCharTextDelim = false;
continue;
}
}
if (previousCharTextDelim)
{
// Non-text delimiter foudn after text delimiter - End of text field.
inTextField = false;
previousCharTextDelim = false;
if (c == fieldDelimiter)
{
// End of field.
fields.Add(currentField);
currentField = "";
continue;
}
continue;
}
currentField += c;
}
else
{
// Non-text field.
if (c == fieldDelimiter)
{
// End of field.
fields.Add(currentField);
currentField = "";
continue;
}
if (currentField.Length == 0 && c == textDelimiter)
{
// First character of field is text delimiter.
inTextField = true;
continue;
}
// Append character to field.
currentField += c;
}
}
fields.Add(currentField);
return fields;
}
//-------------------------------------------------------------------
}
//=======================================================================
}