Browse Source

Fixed CsvParser lineendings

master
chrisgregan 9 years ago
parent
commit
1021b15036
  1. 414
      Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs

414
Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs vendored

@ -5,215 +5,215 @@ using System.Text;
namespace Ideafixxxer.CsvParser namespace Ideafixxxer.CsvParser
{ {
public class CsvParser public class CsvParser
{ {
private const char CommaCharacter = ','; private const char CommaCharacter = ',';
private const char QuoteCharacter = '"'; private const char QuoteCharacter = '"';
#region Nested types #region Nested types
private abstract class ParserState private abstract class ParserState
{ {
public static readonly LineStartState LineStartState = new LineStartState(); public static readonly LineStartState LineStartState = new LineStartState();
public static readonly ValueStartState ValueStartState = new ValueStartState(); public static readonly ValueStartState ValueStartState = new ValueStartState();
public static readonly ValueState ValueState = new ValueState(); public static readonly ValueState ValueState = new ValueState();
public static readonly QuotedValueState QuotedValueState = new QuotedValueState(); public static readonly QuotedValueState QuotedValueState = new QuotedValueState();
public static readonly QuoteState QuoteState = new QuoteState(); public static readonly QuoteState QuoteState = new QuoteState();
public abstract ParserState AnyChar(char ch, ParserContext context); public abstract ParserState AnyChar(char ch, ParserContext context);
public abstract ParserState Comma(ParserContext context); public abstract ParserState Comma(ParserContext context);
public abstract ParserState Quote(ParserContext context); public abstract ParserState Quote(ParserContext context);
public abstract ParserState EndOfLine(ParserContext context); public abstract ParserState EndOfLine(ParserContext context);
} }
private class LineStartState : ParserState private class LineStartState : ParserState
{ {
public override ParserState AnyChar(char ch, ParserContext context) public override ParserState AnyChar(char ch, ParserContext context)
{ {
context.AddChar(ch); context.AddChar(ch);
return ValueState; return ValueState;
} }
public override ParserState Comma(ParserContext context) public override ParserState Comma(ParserContext context)
{ {
context.AddValue(); context.AddValue();
return ValueStartState; return ValueStartState;
} }
public override ParserState Quote(ParserContext context) public override ParserState Quote(ParserContext context)
{ {
return QuotedValueState; return QuotedValueState;
} }
public override ParserState EndOfLine(ParserContext context) public override ParserState EndOfLine(ParserContext context)
{ {
context.AddLine(); context.AddLine();
return LineStartState; return LineStartState;
} }
} }
private class ValueStartState : LineStartState private class ValueStartState : LineStartState
{ {
public override ParserState EndOfLine(ParserContext context) public override ParserState EndOfLine(ParserContext context)
{ {
context.AddValue(); context.AddValue();
context.AddLine(); context.AddLine();
return LineStartState; return LineStartState;
} }
} }
private class ValueState : ParserState private class ValueState : ParserState
{ {
public override ParserState AnyChar(char ch, ParserContext context) public override ParserState AnyChar(char ch, ParserContext context)
{ {
context.AddChar(ch); context.AddChar(ch);
return ValueState; return ValueState;
} }
public override ParserState Comma(ParserContext context) public override ParserState Comma(ParserContext context)
{ {
context.AddValue(); context.AddValue();
return ValueStartState; return ValueStartState;
} }
public override ParserState Quote(ParserContext context) public override ParserState Quote(ParserContext context)
{ {
context.AddChar(QuoteCharacter); context.AddChar(QuoteCharacter);
return ValueState; return ValueState;
} }
public override ParserState EndOfLine(ParserContext context) public override ParserState EndOfLine(ParserContext context)
{ {
context.AddValue(); context.AddValue();
context.AddLine(); context.AddLine();
return LineStartState; return LineStartState;
} }
} }
private class QuotedValueState : ParserState private class QuotedValueState : ParserState
{ {
public override ParserState AnyChar(char ch, ParserContext context) public override ParserState AnyChar(char ch, ParserContext context)
{ {
context.AddChar(ch); context.AddChar(ch);
return QuotedValueState; return QuotedValueState;
} }
public override ParserState Comma(ParserContext context) public override ParserState Comma(ParserContext context)
{ {
context.AddChar(CommaCharacter); context.AddChar(CommaCharacter);
return QuotedValueState; return QuotedValueState;
} }
public override ParserState Quote(ParserContext context) public override ParserState Quote(ParserContext context)
{ {
return QuoteState; return QuoteState;
} }
public override ParserState EndOfLine(ParserContext context) public override ParserState EndOfLine(ParserContext context)
{ {
context.AddChar('\r'); context.AddChar('\r');
context.AddChar('\n'); context.AddChar('\n');
return QuotedValueState; return QuotedValueState;
} }
} }
private class QuoteState : ParserState private class QuoteState : ParserState
{ {
public override ParserState AnyChar(char ch, ParserContext context) public override ParserState AnyChar(char ch, ParserContext context)
{ {
//undefined, ignore " //undefined, ignore "
context.AddChar(ch); context.AddChar(ch);
return QuotedValueState; return QuotedValueState;
} }
public override ParserState Comma(ParserContext context) public override ParserState Comma(ParserContext context)
{ {
context.AddValue(); context.AddValue();
return ValueStartState; return ValueStartState;
} }
public override ParserState Quote(ParserContext context) public override ParserState Quote(ParserContext context)
{ {
context.AddChar(QuoteCharacter); context.AddChar(QuoteCharacter);
return QuotedValueState; return QuotedValueState;
} }
public override ParserState EndOfLine(ParserContext context) public override ParserState EndOfLine(ParserContext context)
{ {
context.AddValue(); context.AddValue();
context.AddLine(); context.AddLine();
return LineStartState; return LineStartState;
} }
} }
private class ParserContext private class ParserContext
{ {
private readonly StringBuilder _currentValue = new StringBuilder(); private readonly StringBuilder _currentValue = new StringBuilder();
private readonly List<string[]> _lines = new List<string[]>(); private readonly List<string[]> _lines = new List<string[]>();
private readonly List<string> _currentLine = new List<string>(); private readonly List<string> _currentLine = new List<string>();
public void AddChar(char ch) public void AddChar(char ch)
{ {
_currentValue.Append(ch); _currentValue.Append(ch);
} }
public void AddValue() public void AddValue()
{ {
_currentLine.Add(_currentValue.ToString()); _currentLine.Add(_currentValue.ToString());
_currentValue.Remove(0, _currentValue.Length); _currentValue.Remove(0, _currentValue.Length);
} }
public void AddLine() public void AddLine()
{ {
_lines.Add(_currentLine.ToArray()); _lines.Add(_currentLine.ToArray());
_currentLine.Clear(); _currentLine.Clear();
} }
public List<string[]> GetAllLines() public List<string[]> GetAllLines()
{ {
if (_currentValue.Length > 0) if (_currentValue.Length > 0)
{ {
AddValue(); AddValue();
} }
if (_currentLine.Count > 0) if (_currentLine.Count > 0)
{ {
AddLine(); AddLine();
} }
return _lines; return _lines;
} }
} }
#endregion #endregion
public string[][] Parse(string csvData) public string[][] Parse(string csvData)
{ {
var context = new ParserContext(); var context = new ParserContext();
// Handle both Windows and Mac line endings // Handle both Windows and Mac line endings
string[] lines = csvData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); string[] lines = csvData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
ParserState currentState = ParserState.LineStartState; ParserState currentState = ParserState.LineStartState;
foreach (string next in lines) foreach (string next in lines)
{ {
foreach (char ch in next) foreach (char ch in next)
{ {
switch (ch) switch (ch)
{ {
case CommaCharacter: case CommaCharacter:
currentState = currentState.Comma(context); currentState = currentState.Comma(context);
break; break;
case QuoteCharacter: case QuoteCharacter:
currentState = currentState.Quote(context); currentState = currentState.Quote(context);
break; break;
default: default:
currentState = currentState.AnyChar(ch, context); currentState = currentState.AnyChar(ch, context);
break; break;
} }
} }
currentState = currentState.EndOfLine(context); currentState = currentState.EndOfLine(context);
} }
List<string[]> allLines = context.GetAllLines(); List<string[]> allLines = context.GetAllLines();
return allLines.ToArray(); return allLines.ToArray();
} }
} }
} }
Loading…
Cancel
Save