ASDMValuesParser.h
Go to the documentation of this file.00001 #ifndef ASDMVALUESPARSER_H
00002 #define ASDMVALUESPARSER_H
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 #include <iostream>
00029 #include <vector>
00030 #include <sstream>
00031 #include <boost/regex.hpp>
00032 #include <boost/tokenizer.hpp>
00033 #include <boost/algorithm/string/trim.hpp>
00034
00035 namespace asdm {
00040 class ASDMValuesParserException {
00041
00042 public:
00046 ASDMValuesParserException();
00047
00052 ASDMValuesParserException(const std::string& m);
00053
00057 virtual ~ASDMValuesParserException();
00058
00063 std::string getMessage() const;
00064
00065 protected:
00066 std::string message;
00067
00068 };
00069
00070 inline ASDMValuesParserException::ASDMValuesParserException() : message ("ASDMValuesParserException") {}
00071 inline ASDMValuesParserException::ASDMValuesParserException(const std::string& m) : message(m) {}
00072 inline ASDMValuesParserException::~ASDMValuesParserException() {}
00073 inline std::string ASDMValuesParserException::getMessage() const {
00074 return "ASDMValuesParserException : " + message;
00075 }
00076
00077 class ASDMValuesParser {
00078 private:
00079 static std::istringstream iss;
00080 static std::ostringstream oss;
00081
00082 public:
00083 template<class T>
00084 static void READ(T& v) {
00085 char c;
00086 iss >> v; if (iss.fail() || (iss.get(c) && c != ' ')) {
00087 oss.str("");
00088 oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
00089 throw ASDMValuesParserException(oss.str());
00090 }
00091 iss.putback(c);
00092 }
00093
00094 template<class T>
00095 static T parse(const std::string& s) {
00096 T result;
00097 iss.clear();
00098 iss.str(s);
00099
00100 READ(result);
00101
00102 return result;
00103 }
00104
00105 template<class T>
00106 static std::vector<T> parse1D(const std::string& s) {
00107 int ndim;
00108 int nvalue;
00109
00110 iss.clear();
00111 iss.str(s);
00112 READ(ndim);
00113 if (ndim != 1) {
00114 oss.str("");
00115 oss << "The first field of a 1D array representation should be '1', I found '" << ndim << "' in '" << s << "'.";
00116 throw ASDMValuesParserException(oss.str());
00117 }
00118
00119 READ(nvalue);
00120 if (nvalue <= 0) {
00121 oss.str("");
00122 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue << "'.";
00123 throw ASDMValuesParserException(oss.str());
00124 }
00125
00126 std::vector<T> result(nvalue);
00127 T value;
00128 for ( int i = 0; i < nvalue; i++) {
00129 READ(value);
00130 result[i]=value;
00131 }
00132
00133 return result;
00134 }
00135
00136 template<class T>
00137 static std::vector<std::vector<T> > parse2D(const std::string& s) {
00138 int ndim;
00139 int nvalue1;
00140 int nvalue2;
00141
00142 iss.clear();
00143 iss.str(s);
00144 READ(ndim);
00145 if (ndim != 2) {
00146 oss.str("");
00147 oss << "The first field of a 2D array representation should be '2', I found '" << ndim << "' in '" << s << "'.";
00148 throw ASDMValuesParserException(oss.str());
00149 }
00150
00151 READ(nvalue1);
00152 if (nvalue1 <= 0) {
00153 oss.str("");
00154 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
00155 throw ASDMValuesParserException(oss.str());
00156 }
00157
00158 READ(nvalue2);
00159 if (nvalue2 <= 0) {
00160 oss.str("");
00161 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
00162 throw ASDMValuesParserException(oss.str());
00163 }
00164
00165 std::vector<std::vector<T> > result(nvalue1);
00166 T value;
00167 for ( int i = 0; i < nvalue1; i++) {
00168 std::vector<T> v(nvalue2);
00169 for ( int j = 0; j < nvalue2; j++) {
00170 READ(value);
00171 v[j] = value;
00172 }
00173 result[i] = v;
00174 }
00175 return result;
00176 }
00177
00178 template<class T>
00179 static std::vector<std::vector<std::vector<T> > > parse3D(const std::string& s) {
00180 int ndim;
00181 int nvalue1;
00182 int nvalue2;
00183 int nvalue3;
00184
00185 iss.clear();
00186 iss.str(s);
00187
00188 READ(ndim);
00189 if (ndim != 3) {
00190 oss.str("");
00191 oss << "The first field of a 3D array representation should be '3', I found '" << ndim << "' in '" << s << "'.";
00192 throw ASDMValuesParserException(oss.str());
00193 }
00194
00195 READ(nvalue1);
00196 if (nvalue1 <= 0) {
00197 oss.str("");
00198 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
00199 throw ASDMValuesParserException(oss.str());
00200 }
00201
00202 READ(nvalue2);
00203 if (nvalue2 <= 0) {
00204 oss.str("");
00205 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
00206 throw ASDMValuesParserException(oss.str());
00207 }
00208
00209 READ(nvalue3);
00210 if (nvalue3 <= 0) {
00211 oss.str("");
00212 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue3 << "'.";
00213 throw ASDMValuesParserException(oss.str());
00214 }
00215
00216 std::vector<std::vector<std::vector<T> > > result(nvalue1);
00217 T value;
00218 for ( int i = 0; i < nvalue1; i++) {
00219 std::vector<std::vector<T> >vv(nvalue2);
00220 for ( int j = 0; j < nvalue2; j++) {
00221 std::vector<T> v(nvalue3);
00222 for ( int k = 0; k < nvalue3; k++) {
00223 READ(value);
00224 v[k] = value;
00225 }
00226 vv[j] = v;
00227 }
00228 result[i] = vv;
00229 }
00230 return result;
00231 }
00232
00233 template<class T>
00234 static std::vector<std::vector<std::vector<std::vector<T> > > > parse4D(const std::string& s) {
00235 int ndim;
00236 int nvalue1;
00237 int nvalue2;
00238 int nvalue3;
00239 int nvalue4;
00240
00241 iss.clear();
00242 iss.str(s);
00243 READ(ndim);
00244 if (ndim != 4) {
00245 oss.str("");
00246 oss << "The first field of a 3D array representation should be '4', I found '" << ndim << "' in '" << s << "'.";
00247 throw ASDMValuesParserException(oss.str());
00248 }
00249
00250 READ(nvalue1);
00251 if (nvalue1 <= 0) {
00252 oss.str("");
00253 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
00254 throw ASDMValuesParserException(oss.str());
00255 }
00256
00257 READ(nvalue2);
00258 if (nvalue2 <= 0) {
00259 oss.str("");
00260 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
00261 throw ASDMValuesParserException(oss.str());
00262 }
00263
00264 READ(nvalue3);
00265 if (nvalue3 <= 0) {
00266 oss.str("");
00267 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue3 << "'.";
00268 throw ASDMValuesParserException(oss.str());
00269 }
00270
00271 READ(nvalue4);
00272 if (nvalue4 <= 0) {
00273 oss.str("");
00274 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue4 << "'.";
00275 throw ASDMValuesParserException(oss.str());
00276 }
00277
00278 std::vector<std::vector<std::vector<std::vector<T> > > > result(nvalue1);
00279 T value;
00280 for ( int i = 0; i < nvalue1; i++) {
00281 std::vector<std::vector<std::vector<T> > > vvv(nvalue2);
00282 for ( int j = 0; j < nvalue2; j++) {
00283 std::vector<std::vector<T> > vv(nvalue3);
00284 for ( int k = 0; k < nvalue3; k++) {
00285 std::vector<T> v(nvalue4);
00286 for ( int l = 0; l < nvalue4; l++) {
00287 READ(value);
00288 v[l] = value;
00289 }
00290 vv[k] = v;
00291 }
00292 vvv[j] = vv;
00293 }
00294 result[i] = vvv;
00295 }
00296 return result;
00297 }
00298
00299 static std::string parse(const std::string& s);
00300 static std::vector<std::string> parse1D(const std::string& s);
00301 static std::vector<std::vector<std::string > > parse2D(const std::string& s);
00302 static std::vector<std::vector<std::vector<std::string > > > parse3D(const std::string& s);
00303
00304 static std::vector<std::string> parseQuoted(const std::string& s);
00305
00306 private:
00307 static boost::regex quotedStringRegex;
00308
00309 };
00310
00311 inline std::string ASDMValuesParser::parse(const std::string& s) { return s; }
00312 inline std::vector<std::string> ASDMValuesParser::parse1D( const std::string& s) {
00313 int ndim;
00314 int nvalue;
00315
00316 iss.clear();
00317 iss.str(s);
00318 READ(ndim);
00319 if (ndim != 1) {
00320 oss.str("");
00321 oss << "The first field of a 1D array representation should be '1', I found '" << ndim << "' in '" << s << "'.";
00322 throw ASDMValuesParserException(oss.str());
00323 }
00324
00325 READ(nvalue);
00326 if (nvalue <= 0) {
00327 oss.str("");
00328 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue << "'.";
00329 throw ASDMValuesParserException(oss.str());
00330 }
00331
00332 string remains; getline(iss,remains);
00333 std::vector<std::string> result = parseQuoted(boost::trim_left_copy(remains));
00334 if (nvalue > (int) result.size()) {
00335 oss.str("");
00336 oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
00337 throw ASDMValuesParserException(oss.str());
00338 }
00339 return result;
00340 }
00341
00342 inline std::vector<std::vector<std::string > > ASDMValuesParser::parse2D(const std::string& s) {
00343 int ndim;
00344 int nvalue1;
00345 int nvalue2;
00346
00347 iss.clear();
00348 iss.str(s);
00349 READ(ndim);
00350 if (ndim != 2) {
00351 oss.str("");
00352 oss << "The first field of a 2D array representation should be '2', I found '" << ndim << "' in '" << s << "'.";
00353 throw ASDMValuesParserException(oss.str());
00354 }
00355
00356 READ(nvalue1);
00357 if (nvalue1 <= 0) {
00358 oss.str("");
00359 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
00360 throw ASDMValuesParserException(oss.str());
00361 }
00362
00363 READ(nvalue2);
00364 if (nvalue2 <= 0) {
00365 oss.str("");
00366 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
00367 throw ASDMValuesParserException(oss.str());
00368 }
00369
00370 string remains; getline(iss,remains);
00371 std::vector<std::string> v_s = parseQuoted(boost::trim_left_copy(remains));
00372 if (nvalue1 * nvalue2 > (int) v_s.size()) {
00373 oss.str("");
00374 oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
00375 throw ASDMValuesParserException(oss.str());
00376 }
00377
00378 std::vector<std::vector<std::string> > result(nvalue1);
00379 int start = 0;
00380 for (unsigned int i = 0; i < result.size(); i++) {
00381 start = i*nvalue2;
00382 result[i].assign(v_s.begin()+start, v_s.begin()+start+nvalue2);
00383 }
00384 return result;
00385 }
00386
00387 inline std::vector<std::vector<std::vector<std::string > > > ASDMValuesParser::parse3D(const std::string& s) {
00388 int ndim;
00389 int nvalue1;
00390 int nvalue2;
00391 int nvalue3;
00392
00393 iss.clear();
00394 iss.str(s);
00395 READ(ndim);
00396 if (ndim != 3) {
00397 oss.str("");
00398 oss << "The first field of a 2D array representation should be '2', I found '" << ndim << "' in '" << s << "'.";
00399 throw ASDMValuesParserException(oss.str());
00400 }
00401
00402 READ(nvalue1);
00403 if (nvalue1 <= 0) {
00404 oss.str("");
00405 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
00406 throw ASDMValuesParserException(oss.str());
00407 }
00408
00409 READ(nvalue2);
00410 if (nvalue2 <= 0) {
00411 oss.str("");
00412 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
00413 throw ASDMValuesParserException(oss.str());
00414 }
00415
00416 READ(nvalue3);
00417 if (nvalue3 <= 0) {
00418 oss.str("");
00419 oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue3 << "'.";
00420 throw ASDMValuesParserException(oss.str());
00421 }
00422
00423 string remains; getline(iss,remains);
00424 std::vector<std::string> v_s = parseQuoted(boost::trim_left_copy(remains));
00425 if (nvalue1 * nvalue2 * nvalue3 > (int) v_s.size()) {
00426 oss.str("");
00427 oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
00428 throw ASDMValuesParserException(oss.str());
00429 }
00430
00431 std::vector<std::vector<std::string> > plane(nvalue2);
00432 std::vector<std::vector<std::vector<std::string> > > result(nvalue1, plane);
00433 int start = 0;
00434 for (unsigned int i = 0; i < (unsigned int) nvalue1; i++) {
00435 for (unsigned int j = 0; j < (unsigned int) nvalue2; j++) {
00436 result[i][j].assign(v_s.begin()+start, v_s.begin()+start+nvalue3);
00437 start += nvalue3;
00438 }
00439 }
00440 return result;
00441 }
00442
00443 inline std::vector<std::string> ASDMValuesParser::parseQuoted(const std::string& s) {
00444 string separator1("\\");
00445 string separator2(" ");
00446 string separator3("\"");
00447
00448 boost::escaped_list_separator<char> els(separator1,separator2,separator3);
00449 boost::tokenizer<boost::escaped_list_separator<char> > tok(s, els);
00450 std::vector<std::string> result(tok.begin(), tok.end());
00451 return result;
00452 }
00453 }
00454
00455 #endif