casa
$Rev:20696$
|
00001 #ifndef ASDMVALUESPARSER_H 00002 #define ASDMVALUESPARSER_H 00003 /* 00004 * ALMA - Atacama Large Millimeter Array 00005 * (c) European Southern Observatory, 2002 00006 * (c) Associated Universities Inc., 2002 00007 * Copyright by ESO (in the framework of the ALMA collaboration), 00008 * Copyright by AUI (in the framework of the ALMA collaboration), 00009 * All rights reserved. 00010 * 00011 * This library is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Lesser General Public 00013 * License as published by the Free software Foundation; either 00014 * version 2.1 of the License, or (at your option) any later version. 00015 * 00016 * This library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY, without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this library; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00024 * MA 02111-1307 USA 00025 * 00026 * File ASDMValuesParser.h 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 char c; 00100 READ(result); 00101 //if ( c == ' ' ) iss.putback(c); 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("\\");// let quoted arguments escape themselves 00445 string separator2(" "); // split on spaces 00446 string separator3("\"");// let it have quoted arguments 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 } // End namespace asdm. 00454 00455 #endif