private void UpdateState(int value) { // This switch is marginally faster than a dictionary and significantly faster than Hashtable value = _delimiters.Contains(value) ? Delimiter : value; switch (value) { case NoData: _state = LexingStates.NoData; break; case Delimiter: _state = LexingStates.StartingNextField; break; case EndOfLine: _state = LexingStates.EndOfLine; break; case WindowsEndOfLine: _state = LexingStates.WindowsEndOfLine; break; case Quote: _state = LexingStates.ReadingQuoted; break; default: _state = LexingStates.ReadingField; break; } }
public string GetNextField() { UpdateState(Initialize); while ((_state & BreakCondition) != _state) { var currentValue = _reader.Read(); UpdateState(currentValue); switch (_state) { case LexingStates.WindowsEndOfLine: // just skip because the next character is probably going to be \n continue; case LexingStates.ReadingField: _buffer.Append((char)currentValue); break; case LexingStates.StartingNextField: case LexingStates.EndOfLine: case LexingStates.NoData: break; case LexingStates.ReadingQuoted: currentValue = _reader.Read(); while (currentValue != Quote) { _buffer.Append((char)currentValue); currentValue = _reader.Read(); } _state = LexingStates.ReadingField; continue; default: throw new ArgumentOutOfRangeException($"Unknown state '{_state}'"); } } var field = _buffer.ToString(); _buffer.Clear(); return(field); }