casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ASDMValuesParser.h
Go to the documentation of this file.
1 #ifndef ASDMVALUESPARSER_H
2 #define ASDMVALUESPARSER_H
3 /*
4  * ALMA - Atacama Large Millimeter Array
5  * (c) European Southern Observatory, 2002
6  * (c) Associated Universities Inc., 2002
7  * Copyright by ESO (in the framework of the ALMA collaboration),
8  * Copyright by AUI (in the framework of the ALMA collaboration),
9  * All rights reserved.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY, without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  *
26  * File ASDMValuesParser.h
27  */
28 #include <iostream>
29 #include <vector>
30 #include <sstream>
31 
32 #ifndef WITHOUT_BOOST
33 // regex not currently used here, in commented out code
34 //#include <boost/regex.hpp>
35 #include <boost/algorithm/string/trim.hpp>
36 #include <boost/tokenizer.hpp>
37 #else
38 //#include <regex>
39 #include <alma/ASDM/Misc.h>
40 #endif
41 
42 
43 namespace asdm {
49 
50  public:
55 
60  ASDMValuesParserException(const std::string& m);
61 
66 
71  std::string getMessage() const;
72 
73  protected:
74  std::string message;
75 
76  };
77 
78  inline ASDMValuesParserException::ASDMValuesParserException() : message ("ASDMValuesParserException") {}
79  inline ASDMValuesParserException::ASDMValuesParserException(const std::string& m) : message(m) {}
81  inline std::string ASDMValuesParserException::getMessage() const {
82  return "ASDMValuesParserException : " + message;
83  }
84 
86  private:
87  static std::istringstream iss;
88  static std::ostringstream oss;
89 
90  public:
91  template<class T>
92  static void READ(T& v) {
93  char c;
94  iss >> v; if (iss.fail() || (iss.get(c) && c != ' ')) {
95  oss.str("");
96  oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
97  throw ASDMValuesParserException(oss.str());
98  }
99  iss.putback(c);
100  }
101 
102  template<class T>
103  static T parse(const std::string& s) {
104  T result;
105  iss.clear();
106  iss.str(s);
107  READ(result);
108  return result;
109  }
110 
111  template<class T>
112  static std::vector<T> parse1D(const std::string& s) {
113  int ndim;
114  int nvalue;
115 
116  iss.clear();
117  iss.str(s);
118  READ(ndim);
119  if (ndim != 1) {
120  oss.str("");
121  oss << "The first field of a 1D array representation should be '1', I found '" << ndim << "' in '" << s << "'.";
122  throw ASDMValuesParserException(oss.str());
123  }
124 
125  READ(nvalue);
126  if (nvalue <= 0) {
127  oss.str("");
128  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue << "'.";
129  throw ASDMValuesParserException(oss.str());
130  }
131 
132  std::vector<T> result(nvalue);
133  T value;
134  for ( int i = 0; i < nvalue; i++) {
135  READ(value);
136  result[i]=value;
137  }
138 
139  return result;
140  }
141 
142  template<class T>
143  static std::vector<std::vector<T> > parse2D(const std::string& s) {
144  int ndim;
145  int nvalue1;
146  int nvalue2;
147 
148  iss.clear();
149  iss.str(s);
150  READ(ndim);
151  if (ndim != 2) {
152  oss.str("");
153  oss << "The first field of a 2D array representation should be '2', I found '" << ndim << "' in '" << s << "'.";
154  throw ASDMValuesParserException(oss.str());
155  }
156 
157  READ(nvalue1);
158  if (nvalue1 <= 0) {
159  oss.str("");
160  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
161  throw ASDMValuesParserException(oss.str());
162  }
163 
164  READ(nvalue2);
165  if (nvalue2 <= 0) {
166  oss.str("");
167  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
168  throw ASDMValuesParserException(oss.str());
169  }
170 
171  std::vector<std::vector<T> > result(nvalue1);
172  T value;
173  for ( int i = 0; i < nvalue1; i++) {
174  std::vector<T> v(nvalue2);
175  for ( int j = 0; j < nvalue2; j++) {
176  READ(value);
177  v[j] = value;
178  }
179  result[i] = v;
180  }
181  return result;
182  }
183 
184  template<class T>
185  static std::vector<std::vector<std::vector<T> > > parse3D(const std::string& s) {
186  int ndim;
187  int nvalue1;
188  int nvalue2;
189  int nvalue3;
190 
191  iss.clear();
192  iss.str(s);
193 
194  READ(ndim);
195  if (ndim != 3) {
196  oss.str("");
197  oss << "The first field of a 3D array representation should be '3', I found '" << ndim << "' in '" << s << "'.";
198  throw ASDMValuesParserException(oss.str());
199  }
200 
201  READ(nvalue1);
202  if (nvalue1 <= 0) {
203  oss.str("");
204  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
205  throw ASDMValuesParserException(oss.str());
206  }
207 
208  READ(nvalue2);
209  if (nvalue2 <= 0) {
210  oss.str("");
211  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
212  throw ASDMValuesParserException(oss.str());
213  }
214 
215  READ(nvalue3);
216  if (nvalue3 <= 0) {
217  oss.str("");
218  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue3 << "'.";
219  throw ASDMValuesParserException(oss.str());
220  }
221 
222  std::vector<std::vector<std::vector<T> > > result(nvalue1);
223  T value;
224  for ( int i = 0; i < nvalue1; i++) {
225  std::vector<std::vector<T> >vv(nvalue2);
226  for ( int j = 0; j < nvalue2; j++) {
227  std::vector<T> v(nvalue3);
228  for ( int k = 0; k < nvalue3; k++) {
229  READ(value);
230  v[k] = value;
231  }
232  vv[j] = v;
233  }
234  result[i] = vv;
235  }
236  return result;
237  }
238 
239  template<class T>
240  static std::vector<std::vector<std::vector<std::vector<T> > > > parse4D(const std::string& s) {
241  int ndim;
242  int nvalue1;
243  int nvalue2;
244  int nvalue3;
245  int nvalue4;
246 
247  iss.clear();
248  iss.str(s);
249  READ(ndim);
250  if (ndim != 4) {
251  oss.str("");
252  oss << "The first field of a 3D array representation should be '4', I found '" << ndim << "' in '" << s << "'.";
253  throw ASDMValuesParserException(oss.str());
254  }
255 
256  READ(nvalue1);
257  if (nvalue1 <= 0) {
258  oss.str("");
259  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
260  throw ASDMValuesParserException(oss.str());
261  }
262 
263  READ(nvalue2);
264  if (nvalue2 <= 0) {
265  oss.str("");
266  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
267  throw ASDMValuesParserException(oss.str());
268  }
269 
270  READ(nvalue3);
271  if (nvalue3 <= 0) {
272  oss.str("");
273  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue3 << "'.";
274  throw ASDMValuesParserException(oss.str());
275  }
276 
277  READ(nvalue4);
278  if (nvalue4 <= 0) {
279  oss.str("");
280  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue4 << "'.";
281  throw ASDMValuesParserException(oss.str());
282  }
283 
284  std::vector<std::vector<std::vector<std::vector<T> > > > result(nvalue1);
285  T value;
286  for ( int i = 0; i < nvalue1; i++) {
287  std::vector<std::vector<std::vector<T> > > vvv(nvalue2);
288  for ( int j = 0; j < nvalue2; j++) {
289  std::vector<std::vector<T> > vv(nvalue3);
290  for ( int k = 0; k < nvalue3; k++) {
291  std::vector<T> v(nvalue4);
292  for ( int l = 0; l < nvalue4; l++) {
293  READ(value);
294  v[l] = value;
295  }
296  vv[k] = v;
297  }
298  vvv[j] = vv;
299  }
300  result[i] = vvv;
301  }
302  return result;
303  }
304 
305  static std::string parse(const std::string& s);
306  static std::vector<std::string> parse1D(const std::string& s);
307  static std::vector<std::vector<std::string > > parse2D(const std::string& s);
308  static std::vector<std::vector<std::vector<std::string > > > parse3D(const std::string& s);
309 
310  static std::vector<std::string> parseQuoted(const std::string& s);
311 
312  private:
313  // this value is not currently used anywhere
314  //#ifndef WITHOUT_BOOST
315  // static boost::regex quotedStringRegex;
316  //#else
317  // static std::regex quotedStringRegex;
318  //#endif
319 
320  };
321 
322  inline std::string ASDMValuesParser::parse(const std::string& s) { return s; }
323  inline std::vector<std::string> ASDMValuesParser::parse1D( const std::string& s) {
324  int ndim;
325  int nvalue;
326 
327  iss.clear();
328  iss.str(s);
329  READ(ndim);
330  if (ndim != 1) {
331  oss.str("");
332  oss << "The first field of a 1D array representation should be '1', I found '" << ndim << "' in '" << s << "'.";
333  throw ASDMValuesParserException(oss.str());
334  }
335 
336  READ(nvalue);
337  if (nvalue <= 0) {
338  oss.str("");
339  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue << "'.";
340  throw ASDMValuesParserException(oss.str());
341  }
342 
343  std::string remains; getline(iss,remains);
344 #ifndef WITHOUT_BOOST
345  std::vector<std::string> result = parseQuoted(boost::trim_left_copy(remains));
346 #else
347  std::vector<std::string> result = parseQuoted(asdm::ltrim_copy(remains));
348 #endif
349  if (nvalue > (int) result.size()) {
350  oss.str("");
351  oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
352  throw ASDMValuesParserException(oss.str());
353  }
354  return result;
355  }
356 
357  inline std::vector<std::vector<std::string > > ASDMValuesParser::parse2D(const std::string& s) {
358  int ndim;
359  int nvalue1;
360  int nvalue2;
361 
362  iss.clear();
363  iss.str(s);
364  READ(ndim);
365  if (ndim != 2) {
366  oss.str("");
367  oss << "The first field of a 2D array representation should be '2', I found '" << ndim << "' in '" << s << "'.";
368  throw ASDMValuesParserException(oss.str());
369  }
370 
371  READ(nvalue1);
372  if (nvalue1 <= 0) {
373  oss.str("");
374  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
375  throw ASDMValuesParserException(oss.str());
376  }
377 
378  READ(nvalue2);
379  if (nvalue2 <= 0) {
380  oss.str("");
381  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
382  throw ASDMValuesParserException(oss.str());
383  }
384 
385  std::string remains; getline(iss,remains);
386 #ifndef WITHOUT_BOOST
387  std::vector<std::string> v_s = parseQuoted(boost::trim_left_copy(remains));
388 #else
389  std::vector<std::string> v_s = parseQuoted(asdm::ltrim_copy(remains));
390 #endif
391  if (nvalue1 * nvalue2 > (int) v_s.size()) {
392  oss.str("");
393  oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
394  throw ASDMValuesParserException(oss.str());
395  }
396 
397  std::vector<std::vector<std::string> > result(nvalue1);
398  int start = 0;
399  for (unsigned int i = 0; i < result.size(); i++) {
400  start = i*nvalue2;
401  result[i].assign(v_s.begin()+start, v_s.begin()+start+nvalue2);
402  }
403  return result;
404  }
405 
406  inline std::vector<std::vector<std::vector<std::string > > > ASDMValuesParser::parse3D(const std::string& s) {
407  int ndim;
408  int nvalue1;
409  int nvalue2;
410  int nvalue3;
411 
412  iss.clear();
413  iss.str(s);
414  READ(ndim);
415  if (ndim != 3) {
416  oss.str("");
417  oss << "The first field of a 2D array representation should be '2', I found '" << ndim << "' in '" << s << "'.";
418  throw ASDMValuesParserException(oss.str());
419  }
420 
421  READ(nvalue1);
422  if (nvalue1 <= 0) {
423  oss.str("");
424  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue1 << "'.";
425  throw ASDMValuesParserException(oss.str());
426  }
427 
428  READ(nvalue2);
429  if (nvalue2 <= 0) {
430  oss.str("");
431  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue2 << "'.";
432  throw ASDMValuesParserException(oss.str());
433  }
434 
435  READ(nvalue3);
436  if (nvalue3 <= 0) {
437  oss.str("");
438  oss << "The number of values along one dimension of an array must be expressed by a strictly positive integer.I found '" << nvalue3 << "'.";
439  throw ASDMValuesParserException(oss.str());
440  }
441 
442  std::string remains; getline(iss,remains);
443 #ifndef WITHOUT_BOOST
444  std::vector<std::string> v_s = parseQuoted(boost::trim_left_copy(remains));
445 #else
446  std::vector<std::string> v_s = parseQuoted(asdm::ltrim_copy(remains));
447 #endif
448  if (nvalue1 * nvalue2 * nvalue3 > (int) v_s.size()) {
449  oss.str("");
450  oss << "Error while reading the string to be parsed : '" << iss.str() << "'.";
451  throw ASDMValuesParserException(oss.str());
452  }
453 
454  std::vector<std::vector<std::string> > plane(nvalue2);
455  std::vector<std::vector<std::vector<std::string> > > result(nvalue1, plane);
456  int start = 0;
457  for (unsigned int i = 0; i < (unsigned int) nvalue1; i++) {
458  for (unsigned int j = 0; j < (unsigned int) nvalue2; j++) {
459  result[i][j].assign(v_s.begin()+start, v_s.begin()+start+nvalue3);
460  start += nvalue3;
461  }
462  }
463  return result;
464  }
465 
466  inline std::vector<std::string> ASDMValuesParser::parseQuoted(const std::string& s) {
467 #ifndef WITHOUT_BOOST
468  std::string separator1("\\");// let quoted arguments escape themselves
469  std::string separator2(" "); // split on spaces
470  std::string separator3("\"");// let it have quoted arguments
471 
472  boost::escaped_list_separator<char> els(separator1,separator2,separator3);
473  boost::tokenizer<boost::escaped_list_separator<char> > tok(s, els);
474  std::vector<std::string> result(tok.begin(), tok.end());
475 #else
476  // there is no c++ equivalent to the boost tokenizer, parse the start by character
477  std::vector<std::string> result;
478 
479  // an empty string has no tokens
480  if (s.empty()) {
481  return result;
482  }
483 
484  std::string token;
485  std::string nullString;
486 
487  bool quoted, escaped;
488  quoted = escaped = false;
489 
490  for (std::string::const_iterator it=s.begin(); it!=s.end(); ++it) {
491  if (escaped) {
492  token += *it;
493  escaped = false;
494  } else {
495  if (*it=='\\') {
496  escaped = true;
497  } else {
498  if (quoted) {
499  if (*it=='\"') {
500  quoted = false;
501  } else {
502  token += *it;
503  }
504  } else {
505  if (*it == ' ') {
506  result.push_back(token);
507  token = nullString;
508  } else {
509  if (*it=='\"') {
510  quoted = true;
511  } else {
512  token += *it;
513  }
514  }
515  }
516  }
517  }
518  }
519  result.push_back(token);
520 #endif
521  return result;
522  }
523 } // End namespace asdm.
524 
525 #endif
Elements::const_iterator const_iterator
static std::vector< std::vector< T > > parse2D(const std::string &s)
static std::istringstream iss
static std::vector< T > parse1D(const std::string &s)
ASDMValuesParserException()
An empty contructor.
LatticeExprNode ndim(const LatticeExprNode &expr)
1-argument function to get the dimensionality of a lattice.
static std::vector< std::vector< std::vector< std::vector< T > > > > parse4D(const std::string &s)
static std::vector< std::vector< std::vector< T > > > parse3D(const std::string &s)
static std::vector< std::string > parseQuoted(const std::string &s)
std::string getMessage() const
Returns the message associated to this exception.
const Double c
Fundamental physical constants (SI units):
static void READ(T &v)
static T parse(const std::string &s)
A class to represent an exception thrown during the parsing of the representation of a basic type val...
virtual ~ASDMValuesParserException()
The destructor.
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
static std::ostringstream oss