private State Parse(State state, Row row) { var withQuotesNone = _config.WithQuotes ? 0 : 1; var withQuotesInc = _config.WithQuotes ? 1 : 0; while (state != State.end2) { if (!_currentChunk.MoveNext()) { var remain = _currentChunk.Count - _currentChunkStart; if (remain > 0) { row.AddColumnData(_currentChunk, _currentChunkStart, remain); } _currentChunk.Dispose(); _currentChunk = null; _currentChunkStart = 0; return(state); } var part = _currentChunk.Current; switch (state) { case State.start: switch (part.Key) { case Chunk.TypeEnum.quotes: if (row.LastColumnSize > 0) { throw new InvalidDataException($"Data found before quotation marks, at: {_rowCnt}"); } _currentChunkStart = part.Value + withQuotesNone; state = State.qdata; break; case Chunk.TypeEnum.comma: row.AddColumnData(_currentChunk, _currentChunkStart, part.Value - _currentChunkStart); row.EndColumnData(); _currentChunkStart = part.Value + 1; break; case Chunk.TypeEnum.cr: row.AddColumnData(_currentChunk, _currentChunkStart, part.Value - _currentChunkStart); _currentChunkStart = part.Value + 1; state = State.end1; break; case Chunk.TypeEnum.lf: row.AddColumnData(_currentChunk, _currentChunkStart, part.Value - _currentChunkStart); _currentChunkStart = part.Value + 1; state = State.end2; break; default: throw new InvalidOperationException($"Unexpected operand, at: {_rowCnt}"); } break; case State.qdata: if (part.Key == Chunk.TypeEnum.quotes) { row.AddColumnData(_currentChunk, _currentChunkStart, part.Value - _currentChunkStart + withQuotesInc); _currentChunkStart = part.Value + 1; state = State.qdatanext; } break; case State.qdatanext: if (part.Value - _currentChunkStart != 0) { throw new InvalidDataException($"Unexpected data between quotes, at: {_rowCnt}"); } switch (part.Key) { case Chunk.TypeEnum.comma: row.EndColumnData(); _currentChunkStart = part.Value + 1; state = State.start; break; case Chunk.TypeEnum.quotes: _currentChunkStart = part.Value; state = State.qdata; break; case Chunk.TypeEnum.cr: _currentChunkStart = part.Value + 1; state = State.end1; break; case Chunk.TypeEnum.lf: _currentChunkStart = part.Value + 1; state = State.end2; break; default: throw new InvalidOperationException($"Unexpected operand, at: {_rowCnt}"); } break; case State.end1: if (part.Key != Chunk.TypeEnum.lf || (part.Value != 0 && part.Value - _currentChunkStart != 0)) { throw new InvalidDataException($"Unexpected data between CRLF, at: {_rowCnt}"); } row.EndColumnData(); _currentChunkStart = part.Value + 1; state = State.end2; break; default: throw new InvalidOperationException($"Unexpected state, at: {_rowCnt}"); } } return(state); }