Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "csv.h"
00036
00037 #include "common/wave_ex.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 static bool
00048 getNextValue
00049 (
00050 IN std::istream& in,
00051 IN std::string& val,
00052 IN bool& eol
00053 )
00054 {
00055 ASSERT(in.good(), "bad?");
00056 val = "";
00057 eol = false;
00058
00059
00060 while (!in.eof()) {
00061 char a;
00062 in.read(&a, 1);
00063 if ('\n' == a) {
00064 eol = true;
00065 return true;
00066 } else if (',' == a) {
00067 return true;
00068 }
00069
00070 val += a;
00071 }
00072
00073
00074 return false;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 void
00086 parseCsvStream
00087 (
00088 IN std::istream& in,
00089 IN const VecString& columns,
00090 IN csv_callback_fn callback,
00091 IN void * context
00092 )
00093 {
00094 ASSERT(in.good(), "bad?");
00095 ASSERT(columns.size(), "no columns requested?");
00096 ASSERT(callback, "null callback provided?");
00097
00098
00099
00100
00101
00102 static const int s_maxColumns = 32;
00103 ASSERT((int) columns.size() <= s_maxColumns,
00104 "caller is looking for a lot of columns! (more than %d)",
00105 s_maxColumns);
00106 int mapOut[s_maxColumns];
00107 int N = columns.size();
00108
00109
00110 vec_col_t data;
00111 data.resize(N);
00112 for (int i = 0; i < N; ++i) {
00113 col_data_t& cd = data[i];
00114 cd.col_name = NULL;
00115 cd.value = NULL;
00116 }
00117
00118
00119 bool eol = false;
00120 int idx = 0;
00121 for (; !eol; ++idx) {
00122
00123
00124 mapOut[idx] = -1;
00125
00126
00127 std::string val;
00128 if (!getNextValue(in, val, eol)) {
00129 WAVE_EX(wex);
00130 wex << "Premature end of stream while parsing header";
00131 }
00132
00133
00134
00135 for (int i = 0; i < N; ++i) {
00136 const char * col = columns[i].c_str();
00137 if (!strcmp(col, val.c_str())) {
00138
00139
00140
00141 mapOut[idx] = i;
00142 col_data_t& cd = data[i];
00143 cd.col_name = col;
00144 break;
00145 }
00146 }
00147 }
00148 int nCols = idx;
00149
00150 ASSERT(nCols > 0, "no columns?");
00151 ASSERT(nCols >= N, "read fewer columns (%d) than requested (%d)?",
00152 nCols, N);
00153
00154
00155 for (int i = 0; i < N; ++i) {
00156 col_data_t& cd = data[i];
00157 if (!cd.col_name) {
00158 WAVE_EX(wex);
00159 wex << "Unable to find index " << i << ": '";
00160 wex << columns[i] << "'";
00161 }
00162 }
00163
00164
00165 VecString vals;
00166 vals.resize(N);
00167 std::string val;
00168 while (!in.eof()) {
00169
00170 for (int idx = 0; idx < nCols; ++idx) {
00171 if (!getNextValue(in, val, eol)) {
00172 if (0 == idx) {
00173
00174 break;
00175 }
00176 else if (idx < nCols - 1) {
00177 WAVE_EX(wex);
00178 wex << "Premature end of stream while ";
00179 wex << "parsing data columns";
00180 }
00181 }
00182 if (eol && idx < nCols - 1) {
00183 WAVE_EX(wex);
00184 wex << "Row had only " << (idx + 1);
00185 wex << " columns? Need " << nCols;
00186 }
00187
00188 int j = mapOut[idx];
00189 if (j < 0)
00190 continue;
00191
00192 vals[j] = val;
00193 col_data_t& cd = data[j];
00194 cd.value = vals[j].c_str();
00195 }
00196
00197
00198 callback(context, data);
00199 }
00200 }
00201