00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef UTILS_H_
00025 #define UTILS_H_
00026
00027 #include <vector>
00028 #include <sstream>
00029 #include <boost/date_time/posix_time/posix_time_types.hpp>
00030 #include "fimex/CDMException.h"
00031
00032 namespace MetNoFimex
00033 {
00037 int round(double num);
00038
00043 std::string trim(const std::string& str);
00044
00052 template<class InputIterator>
00053 std::string join(InputIterator start, InputIterator end, std::string delim = ",")
00054 {
00055 if (start == end) return "";
00056 std::ostringstream buffer;
00057 InputIterator current = start++;
00058 while (start != end) {
00059 buffer << *current << delim;
00060 current = start++;
00061 }
00062 buffer << *current;
00063 return buffer.str();
00064 }
00065
00073 template<class InputIterator>
00074 std::string joinPtr(InputIterator start, InputIterator end, std::string delim = ",")
00075 {
00076 if (start == end) return "";
00077 std::ostringstream buffer;
00078 InputIterator current = start++;
00079 while (start != end) {
00080 buffer << **current << delim;
00081 current = start++;
00082 }
00083 buffer << **current;
00084 return buffer.str();
00085 }
00086
00096 std::vector<std::string> tokenize(const std::string& str, const std::string& delimiters = " ");
00097
00098
00102 std::string string2lowerCase(const std::string& str);
00103
00107 template<typename T>
00108 std::string type2string(T in) {
00109 std::ostringstream buffer;
00110 buffer << in;
00111 return buffer.str();
00112 }
00113
00117 template<>
00118 std::string type2string<double>(double in);
00119
00120
00121 template<typename T>
00122 T string2type(std::string s) {
00123 T retVal;
00124 std::stringstream buffer;
00125 buffer << s;
00126 buffer >> retVal;
00127 return retVal;
00128 }
00129
00130 typedef long epoch_seconds;
00135 epoch_seconds posixTime2epochTime(const boost::posix_time::ptime& time);
00136
00137
00143 template<typename T>
00144 std::vector<T> tokenizeDotted(const std::string& str, const std::string& delimiter = ",") throw(CDMException)
00145 {
00146 std::vector<std::string> tokens = tokenize(str, delimiter);
00147 std::vector<T> vals;
00148 bool pricks = false;
00149 for (std::vector<std::string>::iterator tok = tokens.begin(); tok != tokens.end(); ++tok) {
00150 std::string current = trim(*tok);
00151 if (current == "...") {
00152 pricks = true;
00153 } else {
00154 T val = string2type<T>(current);
00155 if (pricks == true) {
00156 pricks = false;
00157 size_t end = vals.size();
00158 if (end < 2) {
00159 throw CDMException("tokenizeDotted: cannot use ... expansion at position " + type2string(end-1) +", need at least two values before");
00160 }
00161 T last = vals[end-1];
00162 T dist = last - vals[end-2];
00163 T curVal = last + dist;
00164 while (curVal < val) {
00165 vals.push_back(curVal);
00166 curVal += dist;
00167 }
00168 }
00169 vals.push_back(val);
00170 }
00171 }
00172 return vals;
00173 }
00174
00176 template<typename OUT>
00177 struct staticCast {
00178 template<typename IN>
00179 OUT operator()(const IN& in) { return static_cast<OUT>(in); }
00180 };
00181
00182
00186 template<typename IN, typename OUT>
00187 class ScaleValue : public std::unary_function<IN, OUT>
00188 {
00189 private:
00190 IN oldFill_;
00191 double oldScale_;
00192 double oldOffset_;
00193 OUT newFill_;
00194 double newScale_;
00195 double newOffset_;
00196 public:
00197 ScaleValue(double oldFill, double oldScale, double oldOffset, double newFill, double newScale, double newOffset) :
00198 oldFill_(static_cast<IN>(oldFill)), oldScale_(oldScale), oldOffset_(oldOffset),
00199 newFill_(static_cast<OUT>(newFill)), newScale_(newScale), newOffset_(newOffset) {}
00200 OUT operator()(const IN& in) const {
00201 if (in == oldFill_ || isinf(static_cast<double>(in))) {
00202 return newFill_;
00203 } else {
00204 return static_cast<OUT>(((oldScale_*in + oldOffset_)-newOffset_)/newScale_);
00205 }
00206 }
00207 };
00208
00212 template<typename IN, typename OUT>
00213 class ChangeMissingValue : public std::unary_function<IN, OUT>
00214 {
00215 private:
00216 IN oldFill_;
00217 OUT newFill_;
00218 public:
00219 ChangeMissingValue(double oldFill, double newFill) :
00220 oldFill_(static_cast<IN>(oldFill)), newFill_(static_cast<OUT>(newFill)) {}
00221 OUT operator()(const IN& in) const {
00222 if (in == oldFill_ || isinf(static_cast<double>(in))) {
00223 return newFill_;
00224 } else {
00225 return static_cast<OUT>(in);
00226 }
00227 }
00228 };
00229
00230 }
00231
00232 #endif