static async IAsyncEnumerable <ICsvLine> Impl(Stream stream, CsvOptions?options) { using var reader = new StreamReader(stream); await foreach (var line in ReadImplAsync(reader, options)) { yield return(line); } }
/// <summary> /// Reads the lines from the csv string. /// </summary> /// <param name="csv">The csv string to read the data from.</param> /// <param name="options">The optional options to use when reading.</param> public static IEnumerable <ICsvLine> ReadFromText(string csv, CsvOptions?options = null) { if (csv == null) { throw new ArgumentNullException(nameof(csv)); } return(ReadFromTextImpl(csv, options)); }
/// <summary> /// Reads the lines from the stream. /// </summary> /// <param name="stream">The stream to read the data from.</param> /// <param name="options">The optional options to use when reading.</param> public static IEnumerable <ICsvLine> ReadFromStream(Stream stream, CsvOptions?options = null) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } return(ReadFromStreamImpl(stream, options)); }
/// <summary> /// Reads the lines from the reader. /// </summary> /// <param name="reader">The text reader to read the data from.</param> /// <param name="options">The optional options to use when reading.</param> public static IEnumerable <ICsvLine> Read(TextReader reader, CsvOptions?options = null) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } return(ReadImpl(reader, options)); }
private static IEnumerable <ICsvLine> ReadFromTextImpl(string csv, CsvOptions?options) { using (var reader = new StringReader(csv)) { foreach (var line in ReadImpl(reader, options)) { yield return(line); } } }
private static IEnumerable <ICsvLine> ReadFromStreamImpl(Stream stream, CsvOptions?options) { using (var reader = new StreamReader(stream)) { foreach (var line in ReadImpl(reader, options)) { yield return(line); } } }
/// <summary> /// Reads the lines from the csv string. /// </summary> /// <param name="csv">The csv string to read the data from.</param> /// <param name="options">The optional options to use when reading.</param> public static IEnumerable <ICsvLineFromMemory> ReadFromMemory(MemoryText csv, CsvOptions?options = null) { // NOTE: Logic is copied in ReadImpl/ReadImplAsync/ReadFromMemory options ??= new CsvOptions(); MemoryText line; var index = 0; var position = 0; MemoryText[]? headers = null; Dictionary <string, int>?headerLookup = null; while (!(line = csv.ReadLine(ref position)).IsEmpty) { index++; if (index <= options.RowsToSkip || options.SkipRow?.Invoke(line, index) == true) { continue; } if (headers == null || headerLookup == null) { InitializeOptions(line.Span, options); var skipInitialLine = options.HeaderMode == HeaderMode.HeaderPresent; headers = skipInitialLine ? GetHeaders(line, options) : CreateDefaultHeaders(line, options); try { headerLookup = headers .Select((h, idx) => (h, idx)) .ToDictionary(h => h.Item1.AsString(), h => h.Item2, options.Comparer); } catch (ArgumentException) { throw new InvalidOperationException("Duplicate headers detected in HeaderPresent mode. If you don't have a header you can set the HeaderMode to HeaderAbsent."); } var aliases = options.Aliases; if (aliases != null) { // NOTE: For each group we need at most 1 match (i.e. SingleOrDefault) foreach (var aliasGroup in aliases) { var groupIndex = -1; foreach (var alias in aliasGroup) { if (headerLookup.TryGetValue(alias, out var aliasIndex)) { if (groupIndex != -1) { throw new InvalidOperationException("Found multiple matches within alias group: " + string.Join(";", aliasGroup)); } groupIndex = aliasIndex; } } if (groupIndex != -1) { foreach (var alias in aliasGroup) { headerLookup[alias] = groupIndex; } } } } if (skipInitialLine) { continue; } } var record = new ReadLineFromMemory(headers, headerLookup, index, line, options); if (options.AllowNewLineInEnclosedFieldValues) { while (record.RawSplitLine.Any(f => CsvLineSplitter.IsUnterminatedQuotedValue(f.AsSpan(), options))) { var nextLine = csv.ReadLine(ref position); if (nextLine.IsEmpty) { break; } line = StringHelpers.Concat(line, options.NewLine, nextLine); record = new ReadLineFromMemory(headers, headerLookup, index, line, options); } } yield return(record); } }
/// <summary> /// Reads the lines from the stream. /// </summary> /// <param name="stream">The stream to read the data from.</param> /// <param name="options">The optional options to use when reading.</param> public static IAsyncEnumerable <ICsvLine> ReadFromStreamAsync(Stream stream, CsvOptions?options = null) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); }