#ifndef CSVREADER_H #define CSVREADER_H #include #include #include // A Field in a CSVRow class CSVField { public: CSVField(int start, int length, bool hasQuotes); // byte offset int start; // length in bytes int length; // contains quotes (use CSVRow::unquote) bool hasQuotes; }; // A Row in a CSV Document class CSVRow { public: CSVRow(std::string *row, const std::string * const filePath=0, long lineNumber=-1, char delimiter=',', char quote='"'); // Return a human readable representation of a CSVRow. std::string toString() const; // Get the value of a field. // fieldIndex starts at 0. // Returns false if fieldIndex is out of bounds or // field could not be converted to the specified type. bool getFieldAsString(unsigned int fieldIndex, std::string *out) const; bool getFieldAsLong(unsigned int fieldIndex, long *out) const; bool getFieldAsInt(unsigned int fieldIndex, int *out) const; bool getFieldAsDouble(unsigned int fieldIndex, double *out) const; std::string getFilePath() const; // Get the line number // starting at 1 for the first line. // Return a value < 0 if there is no line number specified. long getLineNumber() const; unsigned int getNumberOfFields() const; // Get the original string that was quoted using some of the rules from RFC 4180 // Examples: unquote("'abc'", "'") == "abc" // unquote("'ab''c'", "'") == "ab'c" // Fields containing line breaks are not supported. static std::string unquote(const std::string &fieldStr, char quoteChar); // Quotes a string using some of the rules from RFC 4180 // Example: quote("ab'c", "'") == "ab''c" // Fields containing line breaks are not supported. static std::string quote(const std::string &fieldStr, char quoteChar); private: // fill m_fields void parse(char delimiter, char quote); // raw bytes from CSV document std::string *m_row; // each field std::vector m_fields; // file path of the CSV document or NULL const std::string * const m_filePath; long m_lineNumber; // quote character char m_quote; }; // static functions to parse CSV data class CSVReader { public: // callback function signature typedef bool (*RowCallback) (const CSVRow &row, void *userData); // Parse a CSV document given by filePath. // Invokes callback function for each row with the supplied userData. // Stop parsing if callback returns false. // filePath: pointer to a file path or NULL if there is no file specified // Returns false if file cannot be opened. static bool readFromFile(const std::string filePath, RowCallback callback, void *userData, char delimiter=',', char quote='"'); // Parse CSV data from stream. // Could be a std::stringstream or a std::fstream, etc. // Invokes callback function for each row with the supplied userData. // Stop parsing and return false if callback returns false. static bool readFromStream(std::istream &stream, RowCallback callback, void *userData, const std::string * const filePath=0, char delimiter=',', char quote='"'); }; #endif //CSVREADER_H