public async Task <CsvRow> ReadRowAsync() { var endOfStream = false; var rowValues = new List <string>(); if (BaseReader != null) { var inQuote = false; var value = new StringBuilder(); var hasCell = false; ColumnNumber = 0; while (true) { var c = await ReadCharAsync().ConfigureAwait(false); if (!c.HasValue) { endOfStream = true; if (hasCell) { rowValues.Add(value.ToString()); } RowNumber++; break; } ColumnNumber++; var next = BaseReader.Peek(); if (inQuote) { if (c == '\n') { LineNumber++; } else if (c == '\r') { if (next == '\n') { hasCell = true; value.Append(c.Value); c = await ReadCharAsync().ConfigureAwait(false); ColumnNumber++; } LineNumber++; } if (Quote.HasValue && c == Quote) { if (next == Quote) { await ReadCharAsync().ConfigureAwait(false); hasCell = true; value.Append(Quote.Value); } else { inQuote = false; } } else { hasCell = true; value.Append(c.Value); } } else if (c == '\n') { if (hasCell) { rowValues.Add(value.ToString()); } LineNumber++; break; } else if (c == '\r') { if (next == '\n') { BaseReader.Read(); ColumnNumber++; } if (hasCell) { rowValues.Add(value.ToString()); } LineNumber++; break; } else if (Quote.HasValue && c == Quote) { if (value.Length == 0) { inQuote = true; } else { hasCell = true; value.Append(c.Value); } } else if (c == Separator) { rowValues.Add(value.ToString()); value.Clear(); hasCell = false; } else { hasCell = true; value.Append(c.Value); } } } if (rowValues.Count == 0 && endOfStream) { return(null); } if (HasHeaderRow && _columns == null) { _columns = rowValues.Select(CreateColumn).ToArray(); return(await ReadRowAsync().ConfigureAwait(false)); // Read the first row with data } return(CreateRow(_columns, rowValues)); }
public char PeekChar() => EndOfStream ? '\0' : Buffer.Count > 0 ? Buffer.Last() : (char)BaseReader.Peek();