using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Base.Data
{
//=======================================================================
///
/// Very basic CSV data handling.
/// For more advanced CSV features, see SaCsvHelper in SacsWinOffice.
///
public static class SacsCsvHandler
{
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
public static String ToCsv (this IEnumerable 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;
}
//-------------------------------------------------------------------
///
/// Extract comma delimited fields from data record.
/// Fields starting with double quotes are terminated with the next single double quotes character.
/// Embedded double quotes pairs are treated as a single double quotes character.
///
///
///
public static List ParseCsvRecord (String data, char fieldDelimiter = ',', char textDelimiter = '"')
{
List fields = new List();
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;
}
//-------------------------------------------------------------------
}
//=======================================================================
}