/// <summary> /// Reads a line of the CSV file. /// </summary> /// <returns>The CSV line.</returns> protected virtual async Task <string[]> ReadLineAsync() { context.RecordBuilder.Clear(); context.Row++; context.RawRow++; while (true) { if (fieldReader.IsBufferEmpty && !await fieldReader.FillBufferAsync()) { // End of file. if (context.RecordBuilder.Length > 0) { // There was no line break at the end of the file. // We need to return the last record first. context.RecordBuilder.Add(fieldReader.GetField()); return(context.RecordBuilder.ToArray()); } return(null); } context.C = fieldReader.GetChar(); if (context.RecordBuilder.Length == 0 && ((context.C == context.ParserConfiguration.Comment && context.ParserConfiguration.AllowComments) || context.C == '\r' || context.C == '\n')) { await ReadBlankLineAsync(); if (!context.ParserConfiguration.IgnoreBlankLines) { break; } continue; } // Trim start outside of quotes. if (context.C == ' ' && (context.ParserConfiguration.TrimOptions & TrimOptions.Trim) == TrimOptions.Trim) { await ReadSpacesAsync(); fieldReader.SetFieldStart(-1); } if (context.C == context.ParserConfiguration.Quote && !context.ParserConfiguration.IgnoreQuotes) { if (await ReadQuotedFieldAsync()) { break; } } else { if (await ReadFieldAsync()) { break; } } } return(context.RecordBuilder.ToArray()); }