/// <summary> /// Object that drives a state machine that will read a CSV cell by cell. /// </summary> /// <param name="CSVStream"></param> public CsvDriver(Stream CSVStream) { CSVStream.Position = 0; _CSVStream = new StreamReader(CSVStream); currentCell = new StringBuilder(); _table = new List <List <string> >(); _currentRow = new List <string>(); //Initialize all states _defaultState = new DefaultState(this); _quoteState = new QuoteState(this); _secondQuoteState = new SecondQuoteState(this); _endState = new EndState(this); //Set the current state in defaultState _currentState = _defaultState; }
public bool isReadToBuild = false; //是否加入生成列表 public void SetState(CsvState state) { mState = state; }
public static List <String> parseRow(String source, char delimiter, char escapeChar, bool allowStrayQuotes, bool allowTextAfterClosingQuote, bool terminateQuoteOnEndOfFile, bool allowUnquotedNewlines, StringBuilder stringBuilder = null ) { if (source == null) { return(null); } if (stringBuilder == null) { stringBuilder = new StringBuilder(); } else { stringBuilder.Clear(); } List <String> row = new List <String>(); CsvState state = CsvState.StartOfLine; for (int i = 0; i < source.Length; i++) { char c = source[i]; switch (state) { case CsvState.Data: case CsvState.StartOfLine: case CsvState.Seeking: { if (c == '\n' || c == '\r') { if (!allowUnquotedNewlines) { throw new IllegalStateException(String.Format("Line contains a newline that isn't wrapped with quotes: {0}", source)); } state = CsvState.Data; stringBuilder.Append(c); } else if (c == delimiter) { row.Add(stringBuilder.ToString()); stringBuilder.Clear(); state = CsvState.Seeking; } else if (c == escapeChar) { if (state == CsvState.Data) { if (allowStrayQuotes) { stringBuilder.Append(escapeChar); } else { throw new IllegalStateException(String.Format("Line contains a quote that isn't wrapped with quotes: {0}", source)); } } else { state = CsvState.Quoted; } } else { state = CsvState.Data; stringBuilder.Append(c); } break; } case CsvState.Quoted: { if (c == escapeChar) { int next = i + 1 < source.Length ? source[i + 1] : -1; if (next == escapeChar) { i++; // consumes second quote stringBuilder.Append(escapeChar); } else if (next == delimiter) { row.Add(stringBuilder.ToString()); stringBuilder.Clear(); i++; // consumes comma state = CsvState.Seeking; } else if (next == '\n' || next == '\r') { state = CsvState.Data; } else { if (allowTextAfterClosingQuote) { state = CsvState.Data; } else { throw new IllegalStateException(String.Format("Line contains an unexpected character {1} after quote: {0}", source, (char)next)); } } } else { stringBuilder.Append(c); } break; } } } switch (state) { case CsvState.StartOfLine: return(null); case CsvState.Quoted: if (!terminateQuoteOnEndOfFile) { throw new IllegalStateException("String ends with open quotes"); } break; } row.Add(stringBuilder.ToString()); return(row); }
protected virtual List <String> readRow(int rowNumber) { List <String> row = new List <String>(); stringBuilder.Clear(); if (endOfFile) { return(null); } int num; CsvState state = CsvState.StartOfLine; while ((num = reader.Read()) != -1) { switch (state) { case CsvState.Data: case CsvState.StartOfLine: case CsvState.Seeking: { if (num == '\n') { updateStreamInformation(rowNumber, "\n"); if (state != CsvState.StartOfLine) { row.Add(stringBuilder.ToString()); } return(row); } else if (num == '\r') { if (reader.Peek() == '\n') { reader.Read(); // consumes both \r\n updateStreamInformation(rowNumber, "\r\n"); } else { updateStreamInformation(rowNumber, "\r"); } if (state != CsvState.StartOfLine) { row.Add(stringBuilder.ToString()); } return(row); } else if (num == settings.delimiter) { row.Add(stringBuilder.ToString()); stringBuilder.Clear(); state = CsvState.Seeking; } else if (num == settings.escapeChar) { if (state == CsvState.Data) { if (settings.allowStrayQuotes) { stringBuilder.Append(settings.escapeChar); } else { throw new IllegalStateException(String.Format("Line {0} contains a quote that isn't wrapped with quotes", rowNumber + 1)); } } else { state = CsvState.Quoted; } } else { state = CsvState.Data; stringBuilder.Append((char)num); } break; } case CsvState.Quoted: { if (num == settings.escapeChar) { int next = reader.Peek(); if (next == settings.escapeChar) { reader.Read(); // consumes second quote stringBuilder.Append(settings.escapeChar); } else if (next == settings.delimiter) { row.Add(stringBuilder.ToString()); stringBuilder.Clear(); reader.Read(); // consumes comma state = CsvState.Seeking; } else if (next == '\n' || next == '\r' || next == -1) { state = CsvState.Data; } else { if (settings.allowTextAfterClosingQuote) { state = CsvState.Data; } else { throw new IllegalStateException(String.Format("Line {0} contains an unexpected character {1} after quote", rowNumber + 1, (char)next)); } } } else { stringBuilder.Append((char)num); } break; } } } endOfFile = true; updateStreamInformation(rowNumber, null); switch (state) { case CsvState.StartOfLine: if (rowNumber > 0) { streamInformation.endsWithNewLine = true; } return(null); case CsvState.Quoted: if (!settings.terminateQuoteOnEndOfFile) { throw new IllegalStateException("File ends with open quotes"); } break; } row.Add(stringBuilder.ToString()); return(row); }
public void SetStateToEndState() { _currentState = _endState; }
public void SetStateToSecondQuoteState() { _currentState = _secondQuoteState; }
public void SetStateToQuoteState() { _currentState = _quoteState; }
public void SetStateToDefaultState() { _currentState = _defaultState; }