/// <summary> /// Exposes the records in a <see cref="CsvReader"/> as an enumeration of <see cref="DataRecord"/>. /// </summary> /// <param name="this"> /// The data source. /// </param> /// <param name="readHeader"> /// If <see langword="true"/>, the first record in <paramref name="this"/> will be read in as the header record. /// </param> /// <returns> /// An enumerable of all records in <paramref name="this"/>. /// </returns> public static IEnumerable <DataRecord> ToEnumerable(this CsvReader @this, bool readHeader = false) { @this.AssertNotNull(nameof(@this)); if (readHeader && @this.HasMoreRecords) { @this.ReadHeaderRecord(); } while (@this.HasMoreRecords) { yield return(@this.ReadDataRecord()); } }
/// <summary> /// Copies all remaining records in <paramref name="this"/> to <paramref name="destination"/>. /// </summary> /// <param name="this"> /// The data source. /// </param> /// <param name="destination"> /// The data destination. /// </param> /// <returns> /// The number of records written to <paramref name="destination"/>. /// </returns> public static int CopyTo(this CsvReader @this, CsvWriter destination) { @this.AssertNotNull("@this"); destination.AssertNotNull("destination"); var num = 0; var buffer = new DataRecord[16]; var read = 0; while ((read = @this.ReadDataRecords(buffer, 0, buffer.Length)) != 0) { destination.WriteRecords(buffer, 0, read); num += read; } return(num); }
/// <summary> /// Populates <paramref name="this"/> with data read asynchronously from <paramref name="csvReader"/>. /// </summary> /// <remarks> /// <para> /// If <paramref name="this"/> has columns defined, those columns will be used when populating the data. If no columns have been defined, <paramref name="csvReader"/> must have a /// <see cref="HeaderRecord"/>, which is then used to define the columns for <paramref name="this"/>. If any data record has more values than can fit into the columns defined on /// <paramref name="this"/>, an exception is thrown. /// </para> /// </remarks> /// <param name="this"> /// The <see cref="DataTable"/>. /// </param> /// <param name="csvReader"> /// The <see cref="CsvReader"/>. /// </param> /// <param name="maximumRecords"> /// The maximum number of records to read and add to <paramref name="this"/>. /// </param> /// <returns> /// The number of rows added to <paramref name="this"/> (and therefore the number of data records read from <paramref name="csvReader"/>). /// </returns> public async static Task <int> FillAsync(this DataTable @this, CsvReader csvReader, int?maximumRecords) { @this.AssertNotNull("@this"); csvReader.AssertNotNull("csvReader"); exceptionHelper.ResolveAndThrowIf(maximumRecords.GetValueOrDefault() < 0, "maximumRecordsMustBePositive"); if (@this.Columns.Count == 0) { // table has no columns, so we need to use the CSV header record to populate them exceptionHelper.ResolveAndThrowIf(csvReader.HeaderRecord == null, "noColumnsAndNoHeaderRecord"); foreach (var columnName in csvReader.HeaderRecord) { @this.Columns.Add(columnName); } } var remaining = maximumRecords.GetValueOrDefault(int.MaxValue); var buffer = new DataRecord[16]; while (remaining > 0) { var read = await csvReader.ReadDataRecordsAsync(buffer, 0, Math.Min(buffer.Length, remaining)).ConfigureAwait(false); if (read == 0) { // no more data break; } for (var i = 0; i < read; ++i) { var record = buffer[i]; exceptionHelper.ResolveAndThrowIf(record.Count > @this.Columns.Count, "moreValuesThanColumns", @this.Columns.Count, record.Count); var recordAsStrings = new string[record.Count]; record.CopyTo(recordAsStrings, 0); @this.Rows.Add(recordAsStrings); } remaining -= read; } return(maximumRecords.GetValueOrDefault(int.MaxValue) - remaining); }
/// <summary> /// Asynchronously copies all remaining records in <paramref name="this"/> to <paramref name="destination"/>. /// </summary> /// <param name="this"> /// The data source. /// </param> /// <param name="destination"> /// The data destination. /// </param> /// <returns> /// The number of records written to <paramref name="destination"/>. /// </returns> public async static Task <int> CopyToAsync(this CsvReader @this, CsvWriter destination) { @this.AssertNotNull("@this"); destination.AssertNotNull("destination"); var num = 0; var buffer = new DataRecord[16]; var read = 0; while ((read = await @this.ReadDataRecordsAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) != 0) { await destination.WriteRecordsAsync(buffer, 0, read).ConfigureAwait(false); num += read; } return(num); }
/// <summary> /// Populates <paramref name="this"/> with data read asynchronously from <paramref name="csvReader"/>. /// </summary> /// <remarks> /// <para> /// If <paramref name="this"/> has columns defined, those columns will be used when populating the data. If no columns have been defined, <paramref name="csvReader"/> must have a /// <see cref="HeaderRecord"/>, which is then used to define the columns for <paramref name="this"/>. If any data record has more values than can fit into the columns defined on /// <paramref name="this"/>, an exception is thrown. /// </para> /// </remarks> /// <param name="this"> /// The <see cref="DataTable"/>. /// </param> /// <param name="csvReader"> /// The <see cref="CsvReader"/>. /// </param> /// <param name="maximumRecords"> /// The maximum number of records to read and add to <paramref name="this"/>. /// </param> /// <returns> /// The number of rows added to <paramref name="this"/> (and therefore the number of data records read from <paramref name="csvReader"/>). /// </returns> public async static Task<int> FillAsync(this DataTable @this, CsvReader csvReader, int? maximumRecords) { @this.AssertNotNull("@this"); csvReader.AssertNotNull("csvReader"); exceptionHelper.ResolveAndThrowIf(maximumRecords.GetValueOrDefault() < 0, "maximumRecordsMustBePositive"); if (@this.Columns.Count == 0) { // table has no columns, so we need to use the CSV header record to populate them exceptionHelper.ResolveAndThrowIf(csvReader.HeaderRecord == null, "noColumnsAndNoHeaderRecord"); foreach (var columnName in csvReader.HeaderRecord) { @this.Columns.Add(columnName); } } var remaining = maximumRecords.GetValueOrDefault(int.MaxValue); var buffer = new DataRecord[16]; while (remaining > 0) { var read = await csvReader.ReadDataRecordsAsync(buffer, 0, Math.Min(buffer.Length, remaining)).ConfigureAwait(false); if (read == 0) { // no more data break; } for (var i = 0; i < read; ++i) { var record = buffer[i]; exceptionHelper.ResolveAndThrowIf(record.Count > @this.Columns.Count, "moreValuesThanColumns", @this.Columns.Count, record.Count); var recordAsStrings = new string[record.Count]; record.CopyTo(recordAsStrings, 0); @this.Rows.Add(recordAsStrings); } remaining -= read; } return maximumRecords.GetValueOrDefault(int.MaxValue) - remaining; }