File: CsvUtil.C

package info (click to toggle)
witty 3.3.3%2Bdfsg-4.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 28,228 kB
  • ctags: 26,694
  • sloc: cpp: 147,809; ansic: 77,999; xml: 16,331; sh: 1,303; makefile: 198; java: 86; sql: 14
file content (97 lines) | stat: -rw-r--r-- 2,204 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <fstream>

#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>

#include <Wt/WAbstractItemModel>
#include <Wt/WStandardItemModel>
#include <Wt/WStandardItem>
#include <Wt/WString>

#include "CsvUtil.h"

/*
 * A standard item which converts text edits to numbers
 */
class NumericItem : public Wt::WStandardItem {
public:
  virtual NumericItem *clone() const {
    return new NumericItem();
  }

  virtual void setData(const boost::any &data, int role = Wt::UserRole) {
    boost::any dt;

    if (role == Wt::EditRole) {
      std::string s = Wt::asString(data).toUTF8();

      char *end;
      double d = std::strtod(s.c_str(), &end);
      if (*end == 0)
	dt = boost::any(d);
      else
	dt = data;
    }

    Wt::WStandardItem::setData(dt, role);
  }
};

Wt::WStandardItemModel *csvToModel(const std::string& csvFile,
				   Wt::WObject *parent,
				   bool firstLineIsHeaders)
{
  std::ifstream f(csvFile.c_str());

  if (f) {
    Wt::WStandardItemModel *result = new Wt::WStandardItemModel(0, 0, parent);
    result->setItemPrototype(new NumericItem());
    readFromCsv(f, result, -1, firstLineIsHeaders);
    return result;
  } else
    return 0;
}

void readFromCsv(std::istream& f, Wt::WAbstractItemModel *model,
		 int numRows, bool firstLineIsHeaders)
{
  int csvRow = 0;

  while (f) {
    std::string line;
    getline(f, line);

    if (f) {
      typedef boost::tokenizer<boost::escaped_list_separator<char> >
	CsvTokenizer;
      CsvTokenizer tok(line);

      int col = 0;
      for (CsvTokenizer::iterator i = tok.begin();
	   i != tok.end(); ++i, ++col) {

	if (col >= model->columnCount())
	  model->insertColumns(model->columnCount(),
			       col + 1 - model->columnCount());

	if (firstLineIsHeaders && csvRow == 0)
	  model->setHeaderData(col, boost::any(Wt::WString::fromUTF8(*i)));
	else {
	  int dataRow = firstLineIsHeaders ? csvRow - 1 : csvRow;

	  if (numRows != -1 && dataRow >= numRows)
	    return;

	  if (dataRow >= model->rowCount())
	    model->insertRows(model->rowCount(),
			      dataRow + 1 - model->rowCount());

	  boost::any data(Wt::WString::fromUTF8(*i));
	  model->setData(dataRow, col, data);
	}
      }
    }

    ++csvRow;
  }
}