swallow_csv.cpp
Go to the documentation of this file.
1 //
2 // Efficient CSV Reader for MATLAB
3 //
4 // Copyright (C) 2012, Stanislaw Adaszewski
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 #include <mex.h>
21 #include <vector>
22 #include <string>
23 
24 using namespace std;
25 
26 static double zero = 0.0;
27 static double NaN = zero / 0;
28 
29 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
30  if (nrhs < 1 || nrhs > 4 || nlhs != 2) {
31  mexErrMsgTxt("Usage: [numbers, text] = swallow_csv(filename, [quote, [sep, [escape]]])");
32  }
33 
34  for (int i = 0; i < nrhs; i++) {
35  if (!mxIsChar(prhs[i]) || mxIsEmpty(prhs[i])) {
36  mexErrMsgTxt("Usage: [numbers, text] = swallow_csv(filename, [quote, [sep, [escape]]])");
37  }
38  }
39 
40  char quote = '"';
41  char sep = ';';
42  char escape = '\\';
43 
44  if (nrhs > 1) {
45  quote = mxGetChars(prhs[1])[0] & 0xff;
46  if (nrhs > 2) {
47  sep = mxGetChars(prhs[2])[0] & 0xff;
48  if (nrhs > 3) {
49  escape = mxGetChars(prhs[3])[0] & 0xff;
50  }
51  }
52  }
53 
54  char filename[1024];
55  mxGetString(prhs[0], filename, 1024);
56  FILE *f = fopen(filename, "rb");
57  if (!f) {
58  mexErrMsgTxt("Couldn't open specified file");
59  }
60  char buf[4096];
61  int state = 0;
62  vector<vector<string> > data;
63  string cell;
64  vector<string> row;
65  size_t max_columns = 0;
66 
67  while (true) {
68  size_t n = fread(buf, 1, 4096, f);
69  if (n == 0) {
70  break;
71  }
72  for (size_t i = 0; i < n; i++) {
73  switch(state) {
74  case 0: // virgin state
75  if (buf[i] == quote) {
76  state = 1; // quoted string
77  } else if (buf[i] == sep) {
78  row.push_back(cell);
79  cell = "";
80  } else if (buf[i] == '\r') {
81  // do nothing
82  } else if (buf[i] == '\n') {
83  row.push_back(cell);
84  cell = "";
85  if (row.size() > max_columns) {
86  max_columns = row.size();
87  }
88  data.push_back(row);
89  row.clear();
90  } else {
91  cell += buf[i];
92  }
93  break;
94  case 1: // quoted string
95  if (buf[i] == escape) {
96  state = 2; // escaped state
97  } else if (buf[i] == quote) {
98  state = 3; // potential double quote
99  } else {
100  cell += buf[i];
101  }
102  break;
103  case 2: // escaped
104  if (buf[i] == 'n') {
105  cell += '\n';
106  } else if (buf[i] == 't') {
107  cell += '\t';
108  } else if (buf[i] == 'r') {
109  cell += '\r';
110  } else if (buf[i] == quote) {
111  cell += quote;
112  } else {
113  mexErrMsgTxt("Encountered unknown escape sequence.");
114  }
115  state = 1;
116  break;
117  case 3: // potential double quote
118  if (buf[i] == quote) {
119  cell += quote;
120  state = 1; // quoted string continues
121  } else {
122  state = 0; // parse it in the regular way
123  i--;
124  }
125  break;
126  }
127  }
128  }
129 
130  fclose(f);
131 
132  mwSize dims[] = {(mwSize) data.size(), (mwSize) max_columns};
133  plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
134  plhs[1] = mxCreateCellArray(2, dims);
135 
136  double *p = mxGetPr(plhs[0]);
137 
138  for (int i = 0; i < data.size(); i++) {
139  vector<string> &row(data[i]);
140  for (int j = 0; j < row.size(); j++) {
141  char *nptr = (char*) row[j].c_str();
142  char *endptr;
143  double d = strtod(nptr, &endptr);
144  if (row[j].size() == 0 || endptr != nptr + row[j].size()) {
145  p[j * data.size() + i] = NaN;
146  mxArray *tmp = mxCreateString(nptr);
147  mxSetCell(plhs[1], (int)(j * data.size() + i), tmp);
148  } else {
149  p[j * data.size() + i] = d;
150  }
151  }
152  for (int j = row.size(); j < max_columns; j++) {
153  p[j * data.size() + i] = NaN;
154  }
155  }
156 }
d
f
static double zero
Definition: swallow_csv.cpp:26
static double NaN
Definition: swallow_csv.cpp:27
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Definition: swallow_csv.cpp:29


timesync_ros
Author(s): Juraj Oršulić
autogenerated on Mon Jun 10 2019 15:28:33