Loading...
Searching...
No Matches
VariableFormatter.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32#ifndef VARIABLE_FORMATTER_H_
33#define VARIABLE_FORMATTER_H_
34
35#include <drain/Log.h>
36#include <map>
37#include <list>
38#include <iterator>
39#include <sstream>
40
41#include <drain/Convert.h>
42#include <drain/RegExp.h>
43#include <drain/String.h>
44// #include <drain/VariableAssign.h>
45#include <drain/SmartMapTools.h>
46//#include "Variable.h"
47
48#include "IosFormat.h"
49//#include "MapTools.h"
50
51//#include "Sprinter.h"
52#include "Time.h"
53
54namespace drain {
55
56
58
70template <class T=std::string>
72
73public:
74
75 inline virtual
77
78 IosFormat iosFormat;
79
80 typedef std::map<std::string,T> map_t;
81
83
87 virtual
88 bool handle(const std::string & key, const map_t & variables, std::ostream & ostr) const {
89
90 drain::Logger mout(__FILE__, __FUNCTION__);
91
92 std::string k,format;
93 drain::StringTools::split2(key, k, format, '|');
94 // mout.attention("split '", key, "' to ", k, " + ", format);
95
96 const typename std::map<std::string,T>::const_iterator it = variables.find(k);
97 if (it == variables.end()) {
98 // Don't format.
99 return false;
100 }
101
102
103 if (format.empty()){
104 iosFormat.copyTo(ostr);
105 //vostr.width(width);
106 //vstd::cerr << __FILE__ << " assign -> " << stringlet << std::endl;
107 //vstd::cerr << __FILE__ << " assign <---- " << mit->second << std::endl;
108 ostr << it->second;
109 return true;
110 }
111 else {
112 // mout.attention("delegating '", k, "' to formatVariable: ", format);
113 //return formatVariable(k, variables, format, ostr);
114 return formatVariable(k, it->second, format, ostr);
115 }
116
117 }
118
119
121
126 // NOTE: must return false, if not found. Then, further processors may handle the variable tag (remove, change, leave it).
127 virtual
128 bool formatVariable(const std::string & key, const T & value, const std::string & format, std::ostream & ostr) const {
129 // drain::Logger mout(__FILE__, __FUNCTION__);
130 // Default implementation discards \c key.
131 return formatValue(value, format, ostr);
132 }
133
135 virtual inline
136 bool formatVariable(const std::string & key, const T & value, const std::string & format, std::string & str) const final {
137 std::stringstream sstr;
138 const bool result = formatVariable(key, value, format, sstr);
139 str = sstr.str();
140 return result;
141 }
142
143
145
148 static
149 bool formatValue(const T & value, const std::string & format, std::ostream & ostr) {
150
151 drain::Logger mout(__FILE__, __FUNCTION__);
152
153 const char firstChar = format.at(0);
154 const char lastChar = format.at(format.size()-1);
155
156 if (firstChar == ':'){
157
158 mout.attention<LOG_DEBUG>("substring extraction: ", format);
159
160 std::string s;
162 //drain::StringTools::import(variable, s);
163
164 std::vector<size_t> v;
165 drain::StringTools::split(format, v, ':');
166 size_t pos = 0;
167 size_t count = s.size();
168
169 switch (v.size()) {
170 case 3:
171 count = v[2];
172 // no break
173 case 2:
174 pos = v[1];
175 if (pos >= s.size()){
176 mout.warn("index ", pos, " greater than size (", s.size(), ") of string value '", s, "' of '", value, "'");
177 return true;
178 }
179 count = std::min(count, s.size()-pos);
180 ostr << s.substr(v[1], count);
181 break;
182 default:
183 mout.warn("unsupported formatting '", format, "' for variable '", value, "'");
184 mout.advice("use :startpos or :startpos:count for substring extraction");
185 }
186 return true;
187
188 }
189 else if (firstChar == '%'){
190
191 mout.attention<LOG_DEBUG>("string formatting: ", format);
192
193 //else if (format.find('%') != std::string::npos){
194 //drain::MapTools::get(variables, key, s);
195
196 const size_t BUFFER_SIZE = 256;
197 char buffer[BUFFER_SIZE];
198 buffer[0] = '\0';
199 size_t n = 0;
200
201 switch (lastChar){
202 case 's':
203 {
204 std::string s;
206 // drain::StringTools::import(variable, s);
207 n = std::sprintf(buffer, format.c_str(), s.c_str());
208 }
209 break;
210 case 'c':
211 {
212 std::string s;
214 //drain::StringTools::import(variable, s);
215 n = std::sprintf(buffer, format.c_str(), s.at(0)); // ?
216 }
217 break;
218 case 'p':
219 mout.unimplemented("pointer type: ", format);
220 break;
221 case 'f':
222 case 'F':
223 case 'e':
224 case 'E':
225 case 'a':
226 case 'A':
227 case 'g':
228 case 'G':
229 {
230 double d = NAN; //nand()
232 // drain::StringTools::import(variable, d);
233 //drain::MapTools::get(variables, key, d);
234 // ostr << d << "=>"; // debugging
235 n = std::sprintf(buffer, format.c_str(), d);
236 }
237 break;
238 case 'd':
239 case 'i':
240 case 'o':
241 case 'u':
242 case 'x':
243 case 'X':
244 {
245 int i = 0;
246 drain::Convert::convert(value, i);
247 // drain::convertAny(variable, i);
248 // drain::StringTools::import(variable, i);
249 // drain::MapTools::get(variables, key, i);
250 // ostr << i << "=>"; // debugging
251 n = std::sprintf(buffer, format.c_str(), i);
252 }
253 break;
254 default:
255 mout.warn("formatting '", format, "' requested for '", value, "' : unsupported type key: '", lastChar, "'");
256 return false; // could be also true, if seen as handled this way?
257 }
258
259 ostr << buffer;
260 if (n > BUFFER_SIZE){
261 mout.fail("formatting with '", format, "' exceeded buffer size (", BUFFER_SIZE, ')');
262 }
263
264 // mout.warn("time formatting '", format, "' requested for '", k, "' not ending with 'time' or 'date'!");
265 }
266
267 return true;
268 }
269
270
271
272};
273
274/*
275inline
276std::ostream & operator<<(std::ostream & ostr, const StringMapper & strmap){
277 return strmap.toStream(ostr);
278}
279*/
280
281
282} // NAMESPACE
283
284#endif /* STRINGMAPPER_H_ */
285
286// Drain
static void convert(const T &src, T &dst)
Trivial case: source and destination are of same class.
Definition Convert.h:94
static void convert(const T &src, T &dst)
Trivial case: source and destination are of same class.
Definition Convert.h:58
Stores precision, fillChar and fieldWidth applied by STD streams.
Definition IosFormat.h:45
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & fail(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:453
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:476
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:511
static bool split2(const std::string &s, T1 &first, T2 &second, const C &separators, const std::string &trimChars=" \t\n")
Splits and trims a given std::string to a std Sequence.
static void split(const std::string &s, T &sequence, const C &separators, const std::string &trimChars=" \t\n")
Splits and trims a given std::string to a std Sequence.
Definition String.h:380
Formats variables to output stream.
Definition VariableFormatter.h:71
static bool formatValue(const T &value, const std::string &format, std::ostream &ostr)
Given a value, print it formatted to stream.
Definition VariableFormatter.h:149
virtual bool formatVariable(const std::string &key, const T &value, const std::string &format, std::ostream &ostr) const
Given a key, retrieve an associated value from the map and print the value formatted into a stream.
Definition VariableFormatter.h:128
virtual bool handle(const std::string &key, const map_t &variables, std::ostream &ostr) const
Searches given key in a map, and if found, processes (formats) the value to ostream....
Definition VariableFormatter.h:88
virtual bool formatVariable(const std::string &key, const T &value, const std::string &format, std::string &str) const final
Checks if variables have ODIM names (keys), and apply special formatting (currently with time stamps)
Definition VariableFormatter.h:136
Definition DataSelector.cpp:1277