Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JEquation.hh
Go to the documentation of this file.
1 #ifndef __JLANG__JEQUATION__
2 #define __JLANG__JEQUATION__
3 
4 #include <string>
5 #include <locale>
6 #include <cstdio>
7 #include <sstream>
8 
9 #include "JLang/JString.hh"
10 #include "JLang/JEquationFacet.hh"
11 #include "JLang/JValue.hh"
12 
13 
14 /**
15  * \author mdejong
16  */
17 
18 namespace JLANG {}
19 namespace JPP { using namespace JLANG; }
20 
21 namespace JLANG {
22 
23 
24  /**
25  * General purpose equation class.
26  *
27  * An equation could have the following formats:
28  *
29  * <pre>
30  * <skip line> "comment" <end of line>
31  * <skip line> "comment" <end of line>
32  * <key> <separator> <value> <end of line>
33  * <key> <separator> <left bracket> <value> <value> <right bracket> <end of line>
34  * <key><division><key> <separator> <value> <end of line>
35  * </pre>
36  * In this:
37  * - lines starting with one of the skip line characters are ignored;
38  * - <tt>key</tt> is the key of the equation;
39  * - <tt>value</tt> is the value of the equation; and
40  * - <tt>' '</tt> could be any of the specified white space characters.
41  *
42  * In case of a division of the key, the value of the equation will include
43  * the following key up to the end of line.
44  * The special characters are defined in the JEquationParameters class.
45  * The use of this class for I/O is handled via the JEquationFacet class.
46  */
47  class JEquation {
48  public:
49  /**
50  * Auxiliary data structure for equation.
51  */
52  template<class T>
53  struct equation_type {
54  /**
55  * Constructor.
56  *
57  * \param __key key
58  * \param __value value
59  */
60  equation_type(const std::string __key,
61  const T& __value) :
62  key (__key),
63  value(__value)
64  {}
65 
66 
67  /**
68  * Write equation to output stream.
69  *
70  * \param out output stream
71  * \param equation equation
72  * \return output stream
73  */
74  friend inline std::ostream& operator<<(std::ostream& out, const equation_type& equation)
75  {
76  using namespace std;
77 
78  ostream::sentry sentry(out);
79 
80  if (sentry) {
81 
82  const locale& loc = out.getloc();
83 
84  if (has_facet<JEquationFacet>(loc)) {
85 
86  const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
87 
88  out << equation.key;
89  out << facet.getDefaultSeparator();
90  out << equation.value;
91  out << facet.getDefaultEndOfLine();
92 
93  } else {
94 
95  out << equation.key;
96  out << '=';
97  out << equation.value;
98  out << endl;
99  }
100  }
101 
102  return out;
103  }
104 
105  std::string key;
106  const T& value;
107  };
108 
109 
110  /**
111  * Auxiliary method to create equation type.
112  *
113  * \param key key
114  * \param value value
115  */
116  template<class T>
117  static inline equation_type<T> make_equation(const std::string& key, const T& value)
118  {
119  return equation_type<T>(key, value);
120  }
121 
122 
123  /**
124  * Default constructor.
125  */
127  key (),
128  sep ('\0'),
129  value()
130  {}
131 
132 
133  /**
134  * Constructor.
135  *
136  * \param facet facet
137  * \param buffer input
138  */
139  JEquation(const std::string& buffer, const JEquationFacet& facet)
140  {
141  setEquation(buffer, facet);
142  }
143 
144 
145  /**
146  * Get key.
147  *
148  * \return key
149  */
150  const std::string& getKey() const
151  {
152  return key;
153  }
154 
155 
156  /**
157  * Get separator.
158  *
159  * \return separator
160  */
161  const char getSeparator() const
162  {
163  return sep;
164  }
165 
166 
167  /**
168  * Get value.
169  *
170  * \return value
171  */
172  const std::string& getValue() const
173  {
174  return value;
175  }
176 
177 
178  /**
179  * Read equation from input stream.
180  *
181  * \param in input stream
182  * \param equation equation
183  * \return input stream
184  */
185  friend inline std::istream& operator>>(std::istream& in, JEquation& equation)
186  {
187  using namespace std;
188 
189  istream::sentry sentry(in, false);
190 
191  if (sentry) {
192 
193  equation = JEquation();
194 
195  const locale& loc = in.getloc();
196 
197  if (has_facet<JEquationFacet>(loc)) {
198 
199  const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
200 
201  ios_base::iostate state = in.rdstate();
202 
203 
204  for (int c; (c = in.peek()) != EOF && facet.isSkipLine((char) c); ) {
205  facet.ignore(in);
206  }
207 
208 
209  if (state == ios_base::goodbit) facet.get(in, istreambuf_iterator<char>(), in, state, equation.key);
210  if (state == ios_base::goodbit) facet.get(in, istreambuf_iterator<char>(), in, state, equation.sep);
211  if (state == ios_base::goodbit) facet.getline(in, equation.value);
212 
213 
214  // remove white spaces and brackets before evaluation
215 
216  if (facet.isSeparator(equation.sep)) {
217 
218  JString::const_iterator p = equation.value. begin();
219  JString::const_reverse_iterator q = equation.value.rbegin();
220 
221  for ( ; ; ++p, ++q) {
222 
223  for ( ; p != equation.value. end() && facet.isWhiteSpace(*p); ++p) {}
224  for ( ; q != equation.value.rend() && facet.isWhiteSpace(*q); ++q) {}
225 
226  if (p == equation.value. end() || *p != facet.getLeftBracket() ||
227  q == equation.value.rend() || *q != facet.getRightBracket()) {
228  break;
229  }
230  }
231 
232  if (p != equation.value.begin() || q != equation.value.rbegin()) {
233  equation.value = string(p, q.base());
234  }
235  }
236 
237  if (state != ios_base::goodbit && state != ios_base::eofbit) {
238  in.setstate(state);
239  }
240 
241  if (!(state & ios_base::eofbit)) {
242  if (!facet.isDivision (equation.sep) &&
243  !facet.isSeparator(equation.sep)) {
244  in.setstate(ios_base::badbit);
245  }
246  }
247 
248  } else {
249 
250  in.setstate(ios_base::failbit);
251  }
252  }
253 
254  return in;
255  }
256 
257 
258  /**
259  * Write equation to output stream.
260  *
261  * \param out output stream
262  * \param equation equation
263  * \return output stream
264  */
265  friend inline std::ostream& operator<<(std::ostream& out, const JEquation& equation)
266  {
267  using namespace std;
268 
269  ostream::sentry sentry(out);
270 
271  if (sentry) {
272 
273  const locale& loc = out.getloc();
274 
275  if (has_facet<JEquationFacet>(loc)) {
276 
277  const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
278 
279  out << equation.key;
280  out << facet.getDefaultSeparator();
281  out << equation.value;
282  out << facet.getDefaultEndOfLine();
283 
284  } else {
285 
286  out << equation.key;
287  out << equation.sep;
288  out << equation.value;
289  out << endl;
290  }
291  }
292 
293  return out;
294  }
295 
296 
297  /**
298  * Set equation.
299  *
300  * \param buffer input
301  * \param facet facet
302  * \return this equation
303  */
304  JEquation& setEquation(const std::string& buffer, const JEquationFacet& facet)
305  {
306  using namespace std;
307 
308  istringstream in(buffer);
309 
310  in.imbue(locale(in.getloc(), facet.clone()));
311 
312  in >> *this;
313 
314  return *this;
315  }
316 
317 
318  /**
319  * Set this equation to its value.
320  *
321  * \param facet facet
322  * \return this equation
323  */
325  {
326  setEquation(getValue(), facet);
327 
328  return *this;
329  }
330 
331 
332  /**
333  * Extract equation.
334  *
335  * \param buffer input
336  * \param facet facet
337  * \return equation
338  */
339  static JEquation valueOf(const std::string& buffer, const JEquationFacet& facet)
340  {
341  return JEquation(buffer, facet);
342  }
343 
344 
345  /**
346  * Convert equation to string.
347  *
348  * \return string
349  */
350  std::string toString() const
351  {
352  std::string buffer;
353 
354  buffer += getKey();
355  buffer += getSeparator();
356  buffer += getValue();
357 
358  return buffer;
359  }
360 
361  protected:
363  char sep;
365  };
366 }
367 
368 #endif
const std::string & getKey() const
Get key.
Definition: JEquation.hh:150
Auxiliary data structure for equation.
Definition: JEquation.hh:53
static JEquation valueOf(const std::string &buffer, const JEquationFacet &facet)
Extract equation.
Definition: JEquation.hh:339
friend std::ostream & operator<<(std::ostream &out, const equation_type &equation)
Write equation to output stream.
Definition: JEquation.hh:74
const std::string & getValue() const
Get value.
Definition: JEquation.hh:172
Wrapper class around STL string class.
Definition: JString.hh:27
Facet class to specify parsing of equations in currect locale (see class JLANG::JEquation).
const char getDefaultSeparator() const
Get default separator character.
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
Definition: JSirene.sh:45
static equation_type< T > make_equation(const std::string &key, const T &value)
Auxiliary method to create equation type.
Definition: JEquation.hh:117
JEquation & setEquation(const JEquationFacet &facet)
Set this equation to its value.
Definition: JEquation.hh:324
std::string toString() const
Convert equation to string.
Definition: JEquation.hh:350
General purpose equation class.
Definition: JEquation.hh:47
friend std::istream & operator>>(std::istream &in, JEquation &equation)
Read equation from input stream.
Definition: JEquation.hh:185
JEquation(const std::string &buffer, const JEquationFacet &facet)
Constructor.
Definition: JEquation.hh:139
char getRightBracket() const
Get right bracket.
equation_type(const std::string __key, const T &__value)
Constructor.
Definition: JEquation.hh:60
istreambuf_iterator get(const istreambuf_iterator __begin, const istreambuf_iterator __end, const std::ios_base &format, std::ios_base::iostate &result, char &buffer) const
Get character.
char getLeftBracket() const
Get left bracket.
do set_variable OUTPUT_DIRECTORY $WORKDIR T
friend std::ostream & operator<<(std::ostream &out, const JEquation &equation)
Write equation to output stream.
Definition: JEquation.hh:265
std::istream & ignore(std::istream &in) const
Ignore characters until next end of line.
std::istream & getline(std::istream &in, std::string &buffer) const
Read characters until next end of line.
JEquation & setEquation(const std::string &buffer, const JEquationFacet &facet)
Set equation.
Definition: JEquation.hh:304
const char getDefaultEndOfLine() const
Get default end of line character.
bool isWhiteSpace(const char c) const
Test for white space character.
bool isSkipLine(const char c) const
Test for skip line character.
virtual JEquationFacet * clone() const
Clone this facet.
bool isSeparator(const char c) const
Test for separator character.
JEquation()
Default constructor.
Definition: JEquation.hh:126
const char getSeparator() const
Get separator.
Definition: JEquation.hh:161
bool isDivision(const char c) const
Test for division character.
char * loc(char *orig)