Isis 3 Programmer Reference
CSVReader.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <string>
8#include <vector>
9#include <numeric>
10#include <iostream>
11#include <sstream>
12#include "IString.h"
13#include "CSVReader.h"
14#include "CollectorMap.h"
15#include "IException.h"
16
17using namespace std;
18
19namespace Isis {
20
35 CSVReader::CSVReader() : _header(false), _skip(0),
36 _delimiter(','), _keepParts(true), _lines(),
37 _ignoreComments(true) { }
38
65 CSVReader::CSVReader(const QString &csvfile, bool header, int skip,
66 const char &delimiter, const bool keepEmptyParts,
67 const bool ignoreComments) :
68 _header(header), _skip(skip), _delimiter(delimiter),
69 _keepParts(keepEmptyParts), _lines(),
70 _ignoreComments(ignoreComments) {
71
72 read(csvfile);
73 }
74
75
97 int CSVReader::columns() const {
98 return ((rows() > 0) ? columns(getTable()) : 0);
99 }
100
117 int CSVReader::columns(const CSVReader::CSVTable &table) const {
118 CSVColumnSummary summary = getColumnSummary(table);
119 return ((summary.size() > 0) ? summary.key(0) : 0);
120 }
121
122
140 void CSVReader::read(const QString &csvfile) {
141 ifstream ifile(csvfile.toLatin1().data(), ios::in);
142 if(!ifile) {
143 QString mess = "Unable to open file [" + csvfile + "]";
144 throw IException(IException::User, mess, _FILEINFO_);
145 }
146
147 _lines.clear();
148 load(ifile);
149 ifile.close();
150 }
151
169 // Return an empty header if we don't have one
170 if((!_header) || (_skip >= rows())) {
171 return (CSVAxis(0));
172 }
173 return (Parser(_lines[_skip], _delimiter, _keepParts).result());
174 }
175
189 // Return an empty header if we don't have one
190 if((index < 0) || (index >= rows())) {
191 return (CSVAxis(0));
192 }
193 return (Parser(_lines[index+firstRowIndex()], _delimiter, _keepParts).result());
194 }
195
196
219 // Return an empty header if we don't have one
220 if(index < 0) {
221 return (CSVAxis(0));
222 }
223
224 int nrows(rows());
225 int nbad(0);
226 CSVAxis column(nrows);
227 Parser parser;
228 for(int i = 0 ; i < nrows ; i++) {
230 if(parser.size() <= index) {
231// column[i] = Parser::TokenType("");
232 nbad++;
233 }
234 else {
235 column[i] = parser(index);
236 }
237 }
238
239 // If we had no good columns (index is invalid) return an empty column
240 return ((nbad == nrows) ? CSVAxis(0) : column);
241 }
242
263 CSVReader::CSVAxis CSVReader::getColumn(const QString &hname) const {
264 // Get the header
265 CSVAxis header(getHeader());
266 QString head = hname.trimmed();
267 for(int i = 0 ; i < header.dim() ; i++) {
268 if(head.toLower() == header[i].trimmed().toLower()) {
269 return (getColumn(i));
270 }
271 }
272
273 // If we reach here, we did not find the column name
274 return (CSVAxis(0));
275 }
276
277
303 CSVTable table(rows());
304 int nrows(rows());
305 Parser parser;
306 for(int row = 0 ; row < nrows ; row++) {
308 table[row] = parser.result();
309 }
310 return (table);
311 }
312
345 const {
346 CSVColumnSummary summary;
347 for(int row = 0 ; row < table.dim() ; row++) {
348 int n(table[row].dim());
349 if(summary.exists(n)) {
350 int &count = summary.get(n);
351 count++;
352 }
353 else {
354 summary.add(n, 1);
355 }
356 }
357
358 return (summary);
359 }
360
373 CSVColumnSummary summary = getColumnSummary(table);
374 return (summary.size() <= 1);
375 }
376
402 std::istream &CSVReader::load(std::istream &ifile) {
403
404 std::string iline;
405 int nlines(0);
406 while(getline(ifile, iline)) {
407 if(!iline.empty()) {
408 if(!(_ignoreComments && (iline[0] == '#'))) {
409 _lines.push_back(iline.c_str());
410 nlines++;
411 }
412 }
413 }
414
415 if(!ifile.eof()) {
416 ostringstream mess;
417 mess << "Error reading line [" << (nlines + 1) << "]" << ends;
418 throw IException(IException::User, mess.str(), _FILEINFO_);
419 }
420
421 return (ifile);
422 }
423
447 std::istream &operator>>(std::istream &is, CSVReader &csv) {
448 return (csv.load(is));
449 }
450
451}
CSV Parser seperates fields (tokens) from a string with a delimeter.
Definition CSVReader.h:69
TokenList result() const
Returns the list of tokens.
Definition CSVReader.h:156
int parse(const QString &str, const char &delimiter=',', bool keepEmptyParts=true)
Parser method accepting string, delimiter and multiple token handling.
Definition CSVReader.h:137
int size() const
Returns the number of tokens in the parsed string.
Definition CSVReader.h:101
Reads strings and parses them into tokens separated by a delimiter character.
Definition CSVReader.h:239
void read(const QString &fname)
Reads the entire contents of a file for subsequent parsing.
bool isTableValid(const CSVTable &table) const
Indicates if all rows have the same number of columns.
CSVAxis getRow(int index) const
Parse and return the requested row by index.
CSVTable getTable() const
Parse and return all rows and columns in a table array.
int rows() const
Reports the number of rows in the table.
Definition CSVReader.h:285
int firstRowIndex() const
Computes the index of the first data.
Definition CSVReader.h:490
CSVColumnSummary getColumnSummary(const CSVTable &table) const
Computes a row summary of the number of distinct columns in table.
CollectorMap< int, int > CSVColumnSummary
Column summary for all rows.
Definition CSVReader.h:249
CSVParser< QString > Parser
Defines single line parser.
Definition CSVReader.h:242
CSVReader()
Default constructor for CSV reader.
Definition CSVReader.cpp:35
std::istream & load(std::istream &ifile)
Reads all lines from the input stream until an EOF is encoutered.
CSVList _lines
List of lines from file.
Definition CSVReader.h:478
char _delimiter
Separator of values.
Definition CSVReader.h:476
int _skip
Number of lines to skip.
Definition CSVReader.h:475
bool _ignoreComments
Ignore comments on read.
Definition CSVReader.h:479
TNT::Array1D< CSVAxis > CSVTable
Table of all rows/columns.
Definition CSVReader.h:248
Parser::TokenList CSVAxis
Row/Column token list.
Definition CSVReader.h:247
bool _keepParts
Keep empty parts between delimiter.
Definition CSVReader.h:477
CSVAxis getColumn(int index) const
Parse and return a column specified by index order.
int columns() const
Determine the number of columns in the input source.
Definition CSVReader.cpp:97
bool _header
Indicates presences of header.
Definition CSVReader.h:474
CSVAxis getHeader() const
Retrieve the header from the input source if it exists.
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
std::istream & operator>>(std::istream &is, CSVReader &csv)
Input read operator for input stream sources.
Namespace for the standard library.