Jpp 19.3.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
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"
11#include "JLang/JValue.hh"
12
13
14/**
15 * \author mdejong
16 */
17
18namespace JLANG {}
19namespace JPP { using namespace JLANG; }
20
21namespace 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> <comment> "comment" <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;
40 * - <tt>comment</tt> marks the start of an inline comment (which is not part of the value); and
41 * - <tt>' '</tt> could be any of the specified white space characters.
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>
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 key key
137 * \param value value
138 */
139 JEquation(const std::string& key, const std::string& value) :
140 key (key),
141 sep ('\0'),
142 value(value)
143 {}
144
145
146 /**
147 * Constructor.
148 *
149 * \param buffer input
150 * \param facet facet
151 */
152 JEquation(const std::string& buffer, const JEquationFacet& facet)
153 {
154 setEquation(buffer, facet);
155 }
156
157
158 /**
159 * Get key.
160 *
161 * \return key
162 */
163 const std::string& getKey() const
164 {
165 return key;
166 }
167
168
169 /**
170 * Get separator.
171 *
172 * \return separator
173 */
174 const char getSeparator() const
175 {
176 return sep;
177 }
178
179
180 /**
181 * Get value.
182 *
183 * \return value
184 */
185 const std::string& getValue() const
186 {
187 return value;
188 }
189
190
191 /**
192 * Read equation from input stream.
193 *
194 * \param in input stream
195 * \param equation equation
196 * \return input stream
197 */
198 friend inline std::istream& operator>>(std::istream& in, JEquation& equation)
199 {
200 using namespace std;
201
202 istream::sentry sentry(in, false);
203
204 if (sentry) {
205
206 equation = JEquation();
207
208 const locale& loc = in.getloc();
209
210 if (has_facet<JEquationFacet>(loc)) {
211
212 const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
213
214 ios_base::iostate state = in.rdstate();
215
216
217 for (int c; (c = in.peek()) != EOF && facet.isSkipLine((char) c); ) {
218 facet.ignore(in);
219 }
220
221
222 if (state == ios_base::goodbit) facet.get(in, istreambuf_iterator<char>(), in, state, equation.key);
223 if (state == ios_base::goodbit) facet.get(in, istreambuf_iterator<char>(), in, state, equation.sep);
224 if (state == ios_base::goodbit) facet.getline(in, equation.value);
225
226
227 // remove white spaces and brackets before evaluation
228
229 if (facet.isSeparator(equation.sep)) {
230
231 JString::const_iterator p = equation.value. begin();
232 JString::const_reverse_iterator q = equation.value.rbegin();
233
234 for ( ; ; ++p, ++q) {
235
236 for ( ; p != equation.value. end() && facet.isWhiteSpace(*p); ++p) {}
237 for ( ; q != equation.value.rend() && facet.isWhiteSpace(*q); ++q) {}
238
239 if (p == equation.value. end() || *p != facet.getLeftBracket() ||
240 q == equation.value.rend() || *q != facet.getRightBracket()) {
241 break;
242 }
243 }
244
245 if (p != equation.value.begin() || q != equation.value.rbegin()) {
246 equation.value = string(p, q.base());
247 }
248 }
249
250 if (state != ios_base::goodbit && state != ios_base::eofbit) {
251 in.setstate(state);
252 }
253
254 if (!(state & ios_base::eofbit)) {
255 if (!facet.isDivision (equation.sep) &&
256 !facet.isSeparator(equation.sep)) {
257 in.setstate(ios_base::badbit);
258 }
259 }
260
261 } else {
262
263 in.setstate(ios_base::failbit);
264 }
265 }
266
267 return in;
268 }
269
270
271 /**
272 * Write equation to output stream.
273 *
274 * \param out output stream
275 * \param equation equation
276 * \return output stream
277 */
278 friend inline std::ostream& operator<<(std::ostream& out, const JEquation& equation)
279 {
280 using namespace std;
281
282 ostream::sentry sentry(out);
283
284 if (sentry) {
285
286 const locale& loc = out.getloc();
287
288 if (has_facet<JEquationFacet>(loc)) {
289
290 const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
291
292 out << equation.key;
293 out << facet.getDefaultSeparator();
294 out << equation.value;
295 out << facet.getDefaultEndOfLine();
296
297 } else {
298
299 out << equation.key;
300 out << equation.sep;
301 out << equation.value;
302 out << endl;
303 }
304 }
305
306 return out;
307 }
308
309
310 /**
311 * Set equation.
312 *
313 * \param buffer input
314 * \param facet facet
315 * \return this equation
316 */
317 JEquation& setEquation(const std::string& buffer, const JEquationFacet& facet)
318 {
319 using namespace std;
320
321 istringstream in(buffer);
322
323 in.imbue(locale(in.getloc(), facet.clone()));
324
325 in >> *this;
326
327 return *this;
328 }
329
330
331 /**
332 * Set this equation to its value.
333 *
334 * \param facet facet
335 * \return this equation
336 */
338 {
339 setEquation(getValue(), facet);
340
341 return *this;
342 }
343
344
345 /**
346 * Extract equation.
347 *
348 * \param buffer input
349 * \param facet facet
350 * \return equation
351 */
352 static JEquation valueOf(const std::string& buffer, const JEquationFacet& facet)
353 {
354 return JEquation(buffer, facet);
355 }
356
357
358 /**
359 * Convert equation to string.
360 *
361 * \return string
362 */
363 std::string toString() const
364 {
365 std::string buffer;
366
367 buffer += getKey();
368 buffer += getSeparator();
369 buffer += getValue();
370
371 return buffer;
372 }
373
374 protected:
376 char sep;
378 };
379}
380
381#endif
Facet class to specify parsing of equations in currect locale (see class JLANG::JEquation).
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.
virtual JEquationFacet * clone() const override
Clone this facet.
bool isSeparator(const char c) const
Test for separator character.
bool isDivision(const char c) const
Test for division character.
const char getDefaultSeparator() const
Get default separator character.
const char getDefaultEndOfLine() const
Get default end of line character.
char getLeftBracket() const
Get left bracket.
bool isSkipLine(const char c) const
Test for skip line character.
char getRightBracket() const
Get right bracket.
bool isWhiteSpace(const char c) const
Test for white space character.
General purpose equation class.
Definition JEquation.hh:47
const std::string & getKey() const
Get key.
Definition JEquation.hh:163
const std::string & getValue() const
Get value.
Definition JEquation.hh:185
JEquation & setEquation(const JEquationFacet &facet)
Set this equation to its value.
Definition JEquation.hh:337
JEquation()
Default constructor.
Definition JEquation.hh:126
JEquation(const std::string &buffer, const JEquationFacet &facet)
Constructor.
Definition JEquation.hh:152
std::string toString() const
Convert equation to string.
Definition JEquation.hh:363
const char getSeparator() const
Get separator.
Definition JEquation.hh:174
friend std::ostream & operator<<(std::ostream &out, const JEquation &equation)
Write equation to output stream.
Definition JEquation.hh:278
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 std::string &buffer, const JEquationFacet &facet)
Set equation.
Definition JEquation.hh:317
friend std::istream & operator>>(std::istream &in, JEquation &equation)
Read equation from input stream.
Definition JEquation.hh:198
JEquation(const std::string &key, const std::string &value)
Constructor.
Definition JEquation.hh:139
static JEquation valueOf(const std::string &buffer, const JEquationFacet &facet)
Extract equation.
Definition JEquation.hh:352
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.
Wrapper class around STL string class.
Definition JString.hh:29
char * loc(char *orig)
Auxiliary classes and methods for language specific functionality.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for equation.
Definition JEquation.hh:53
equation_type(const std::string __key, const T &__value)
Constructor.
Definition JEquation.hh:60
friend std::ostream & operator<<(std::ostream &out, const equation_type &equation)
Write equation to output stream.
Definition JEquation.hh:74