CSV Reader Library

This library contains several classes for parsing and reading CSV data files.

API Documentation

namespace CSV
struct Cursor
#include <Parser.h>

Contains location details of the current record in the source stream.

Public Functions

inline size_t length() const

Get number of source characters in record data.

inline operator String() const

Convenience operator for debugging, etc.

Public Members

int start

BOF if there is no current record.

unsigned end

One-past end of record.

class Parser
#include <Parser.h>

Class to parse a CSV file.

Spec: https://www.ietf.org/rfc/rfc4180.txt

  1. Each record is located on a separate line

  2. Line ending for last record in the file is optional

  3. Field headings are provided either in the source data or in constructor (but not both)

  4. Fields separated with ‘,’ and whitespace considered part of field content

  5. Fields may or may not be quoted - if present, will be removed during parsing

  6. Fields may contain line breaks, quotes or commas

  7. Quotes may be escaped thus “” if field itself is quoted

Additional features:

  • Line breaks can be

    or \r

  • Escapes codes within quoted fields can be converted:

    \r \t “, \

  • Field separator can be changed in constructor

  • Comment lines can be read and returned or discarded

This is a ‘push’ parser so can handle source data of indefinite size.

Subclassed by CSV::Reader

Public Functions

inline Parser(const Options &options)

Construct a CSV parser.

Parameters:

options

bool push(Stream &source)

Read a single data row, taking data if required from provided Stream.

Note

Call flush() after all data pushed

Parameters:

source

Return values:

bool – true if record available, false otherwise

bool push(const char *data, size_t length, size_t &offset)

Read a single data row, taking data if required from provided buffer.

Note

Call flush() after all data pushed

Parameters:
  • data – Buffer containing data to read

  • length – Number of characters in data

  • offset – Read offset in buffer, updated on return

Return values:

bool – true if record available, false otherwise.

bool flush()

Call to read additional rows after all data pushed.

Note

Call repeatedly until returns false

Return values:

bool – true if record available, false otherwise.

bool readRow(IDataSourceStream &source)

Read a single data row using data from provided DataSourceStream.

Note

Returns false only on error or when source.isFinished() returns true.

Return values:

bool – false when there are no more rows

void reset(int offset = BOF)

Reset parser to initial conditions.

Note

Used by Reader when seeking

Parameters:

offset – Initial location for cursor

inline const CStringArray &getRow() const

Get current row.

inline int tell() const

Get cursor position for current row.

The returned value indicates source stream offset for start of current row. After construction cursor is set to -1. This indicates ‘Before first record’ (BOF).

inline const Cursor &getCursor() const

Get cursor position for current row.

inline unsigned getStreamPos() const

Get stream position where next record will be read from.

Public Static Attributes

static constexpr int BOF = {-1}

Indicates ‘Before First Record’.

struct Options
#include <Parser.h>

Parsing options.

Public Members

const char *commentChars = nullptr

Optional list of characters matching start of comment line

uint16_t lineLength = 256

Maximum number of characters in line, including any escapes

char fieldSeparator = ','

Single character such as ‘,’, ‘\t’ or ‘\0’ for whitespace-separated fields with leading/trailing whitespace discarded

bool parseEscape = false

Set to true to handle escape sequences (

, \t, etc.)

bool wantComments = false

Set to true to return comment lines, otherwise they’re discarded.

class Reader : private CSV::Parser
#include <Reader.h>

Class to read a CSV file.

This class

See also

See Parser for details

Subclassed by CSV::Table< Record >

Public Functions

Reader(IDataSourceStream *source, const Options &options, const CStringArray &headings = nullptr)

Construct a CSV reader.

Parameters:
  • source – Stream to read CSV text from, reader takes ownership

  • options

  • headings – Required if source data does not contain field headings as first row

inline Reader(IDataSourceStream *source, char fieldSeparator = ',', const CStringArray &headings = nullptr, uint16_t maxLineLength = 2048)

Construct a CSV reader.

Parameters:
  • source – Stream to read CSV text from

  • fieldSeparator

  • headings – Required if source data does not contain field headings as first row

  • maxLineLength – Limit size of buffer to guard against malformed data

inline void reset()

Reset reader to start of CSV file.

Cursor is set to ‘before start’. Call ‘next()’ to fetch first record.

inline bool next()

Seek to next record.

Return values:

bool – true on success, false if there are no more records

inline unsigned count() const

Get number of columns.

inline const char *getValue(unsigned index) const

Get a value from the current row.

Parameters:

index – Column index, starts at 0

Return values:

const – char* nullptr if index is not valid

inline const char *getValue(const char *name) const

Get a value from the current row.

Parameters:

index – Column name

Return values:

const – char* nullptr if name is not found

inline int getColumn(const char *name) const

Get index of column given its name.

Parameters:

name – Column name to find

Return values:

int – -1 if name is not found

inline explicit operator bool() const

Determine if reader is valid.

inline const CStringArray &getHeadings() const

Get headings.

bool seek(int offset)

Set reader to previously noted position.

If cursor is BOF then there will be no current record until next() is called. This is the same as if next() were called.

Otherwise the corresponding row will be available via getRow().

Note

Source stream must support random seeking (seekFrom)

Parameters:

offset – Value obtained via tell() or Cursor::start

Return values:

bool – true on success, false on failure or end of records

inline const CStringArray &getRow() const

Get current row.

inline const Cursor &getCursor() const

Get cursor position for current row.

inline int tell() const

Get cursor position for current row.

The returned value indicates source stream offset for start of current row. After construction cursor is set to -1. This indicates ‘Before first record’ (BOF).

struct Record
#include <Table.h>

Base class for interpreting a record (line) in a CSV file.

template<class Record = Record>
class Table : public CSV::Reader
#include <Table.h>

Class template for accessing CSV file as set of records.

Template Parameters:

Record – Class inherited from Record

Public Functions

inline Record next()

Fetch next record.

Reader(IDataSourceStream *source, const Options &options, const CStringArray &headings = nullptr)

Construct a CSV reader.

Parameters:
  • source – Stream to read CSV text from, reader takes ownership

  • options

  • headings – Required if source data does not contain field headings as first row

inline Reader(IDataSourceStream *source, char fieldSeparator = ',', const CStringArray &headings = nullptr, uint16_t maxLineLength = 2048)

Construct a CSV reader.

Parameters:
  • source – Stream to read CSV text from

  • fieldSeparator

  • headings – Required if source data does not contain field headings as first row

  • maxLineLength – Limit size of buffer to guard against malformed data

class Iterator
#include <Table.h>

References

Used by

SoC support

  • esp32

  • esp32c2

  • esp32c3

  • esp32s2

  • esp32s3

  • esp8266

  • host

  • rp2040