Skip to content

Commit

Permalink
Add SkippedLinesCount and ReadLinesCount (#12)
Browse files Browse the repository at this point in the history
* Add SkippedLinesCount and ReadLinesCount

* Fix formatting, use consistent naming

* Small formatting fix
  • Loading branch information
kikaragyozov committed Jun 11, 2024
1 parent cb70f0f commit 78c6e32
Showing 1 changed file with 76 additions and 5 deletions.
81 changes: 76 additions & 5 deletions src/NReco.Csv/CsvReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace NReco.Csv {
Expand All @@ -24,6 +22,9 @@ namespace NReco.Csv {
/// <remarks>API is similar to CSVHelper CsvReader.</remarks>
public class CsvReader {

/// <summary>
/// Delimiter used in CSV file.
/// </summary>
public string Delimiter { get; private set; }
int delimLength;

Expand All @@ -40,9 +41,27 @@ public class CsvReader {

TextReader rdr;

/// <summary>
/// Create CSV reader from text reader.
/// </summary>
/// <param name="rdr">
/// Text reader that provides CSV data.
/// </param>
public CsvReader(TextReader rdr) : this(rdr, ",") {
}

/// <summary>
/// Create CSV reader from text reader with custom delimiter.
/// </summary>
/// <param name="rdr">
/// Text reader that provides CSV data.
/// </param>
/// <param name="delimiter">
/// Delimiter used in CSV file.
/// </param>
/// <exception cref="ArgumentException">
/// Thrown when delimiter is empty.
/// </exception>
public CsvReader(TextReader rdr, string delimiter) {
this.rdr = rdr;
Delimiter = delimiter;
Expand All @@ -59,7 +78,8 @@ public CsvReader(TextReader rdr, string delimiter) {
int actualBufferLen = 0;
List<Field> fields = null;
int fieldsCount = 0;
int linesRead = 0;
int readLinesCount = 0;
int skippedLinesCount = 0;

private int ReadBlockAndCheckEof(char[] buffer, int start, int len, ref bool eof) {
if (len == 0)
Expand Down Expand Up @@ -87,7 +107,7 @@ private bool FillBuffer() {
}

private string GetLineTooLongMsg() {
return String.Format("CSV line #{1} length exceedes buffer size ({0})", BufferSize, linesRead);
return String.Format("CSV line #{1} length exceedes buffer size ({0})", BufferSize, readLinesCount);
}

private int ReadQuotedFieldToEnd(int start, int maxPos, bool eof, ref int escapedQuotesCount) {
Expand Down Expand Up @@ -139,12 +159,39 @@ private Field GetOrAddField(int startIdx) {
return f;
}

/// <summary>
/// Number of lines skipped by reader (empty lines).
/// </summary>
public int SkippedLinesCount {
get {
return skippedLinesCount;
}
}

/// <summary>
/// Number of lines read by reader.
/// </summary>
public int ReadLinesCount {
get {
return readLinesCount;
}
}

/// <summary>
/// Number of fields in current CSV line.
/// </summary>
public int FieldsCount {
get {
return fieldsCount;
}
}

/// <summary>
/// Get field value by index.
/// </summary>
/// <param name="idx">
/// Field index (0-based).</param>
/// <returns></returns>
public string this[int idx] {
get {
if (idx < fieldsCount) {
Expand All @@ -155,6 +202,13 @@ public string this[int idx] {
}
}

/// <summary>
/// Get field value length by index.
/// </summary>
/// <param name="idx">
/// Field index (0-based).
/// </param>
/// <returns></returns>
public int GetValueLength(int idx) {
if (idx < fieldsCount) {
var f = fields[idx];
Expand All @@ -163,6 +217,15 @@ public int GetValueLength(int idx) {
return -1;
}

/// <summary>
/// Process field value by index.
/// </summary>
/// <param name="idx">
/// Field index (0-based).
/// </param>
/// <param name="handler">
/// Action that processes field value (char array, start index, length).
/// </param>
public void ProcessValueInBuffer(int idx, Action<char[],int,int> handler) {
if (idx < fieldsCount) {
var f = fields[idx];
Expand All @@ -177,6 +240,13 @@ public void ProcessValueInBuffer(int idx, Action<char[],int,int> handler) {
}
}

/// <summary>
/// Read next CSV line.
/// </summary>
/// <returns>
/// <see langword="true"/> if line was read, <see langword="false"/> if no more data.
/// </returns>
/// <exception cref="InvalidDataException"></exception>
public bool Read() {
Start:
if (fields == null) {
Expand All @@ -197,7 +267,7 @@ public bool Read() {
if (actualBufferLen <= 0) {
return false; // no more data
}
linesRead++;
readLinesCount++;

int maxPos = lineStartPos + actualBufferLen;
int charPos = lineStartPos;
Expand Down Expand Up @@ -276,6 +346,7 @@ public bool Read() {

if (fieldsCount==1 && fields[0].Length==0) {
// skip empty lines
skippedLinesCount++;
goto Start;
}

Expand Down

0 comments on commit 78c6e32

Please sign in to comment.