using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.IO;
using System.Text;
namespace hollyathome.utilities
{
public class CsvParser
{
private List> dataRows = new List>();
private Encoding encoding;
public CsvParser(Stream csvStream, Encoding encoding)
{
StreamReader csvReader = new StreamReader(csvStream, encoding);
ParseCsvStream(csvReader);
this.encoding = encoding;
}
public string GetValue(int row, int col)
{
return dataRows[row][col];
}
public void SetValue(int row, int col, string value)
{
dataRows[row][col] = value;
}
public void ParseCsvStream(StreamReader textReader)
{
bool inQuotedString = false;
int lineLength = 0;
int charPos = 0;
List dataRow = new List();
List data = new List();
string input;
while ((input = textReader.ReadLine()) != null)
{
lineLength = input.Length;
//Loop the input line char by char
for (charPos = 0; charPos < lineLength; charPos++)
{
char curChar = input[charPos];
if (charPos == 0 && curChar == ',')
dataRow.Add(string.Empty);
else if (charPos > 0 && curChar == ',' && !inQuotedString)
{
dataRow.Add(new String(data.ToArray()));
data = new List();
}
else if (curChar == '"')
{
data.Add(curChar);
inQuotedString = !inQuotedString;
}
else
data.Add(curChar);
}
//I'm at the end of the line, but the newline might be part of the data. If so replace the
//newline that ReadLine swallowed earlier
if (inQuotedString)
{
data.Add('\r');
data.Add('\n');
}
else //Otherwise store the row, start a fresh row and carry on.
{
dataRow.Add(new String(data.ToArray()));
data = new List();
dataRows.Add(dataRow);
dataRow = new List();
}
}
}
public void Save(string path)
{
StreamWriter textWriter = new StreamWriter(path, false, encoding);
string seperator = "";
foreach (List row in dataRows)
{
foreach (string data in row)
{
textWriter.Write(String.Format("{0}{1}", seperator, data));
if (seperator == "")
seperator = ",";
}
seperator = "";
textWriter.Write(Environment.NewLine);
}
textWriter.Close();
}
}
}