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 <cmath>
00030 #include <boost/date_time/posix_time/posix_time_types.hpp>
00031 #include "fimex/CDMException.h"
00032
00033 namespace MetNoFimex
00034 {
00038 int round(double num);
00039
00044 std::string trim(const std::string& str);
00045
00053 template<class InputIterator>
00054 std::string join(InputIterator start, InputIterator end, std::string delim = ",")
00055 {
00056 if (start == end) return "";
00057 std::ostringstream buffer;
00058 InputIterator current = start++;
00059 while (start != end) {
00060 buffer << *current << delim;
00061 current = start++;
00062 }
00063 buffer << *current;
00064 return buffer.str();
00065 }
00066
00074 template<class InputIterator>
00075 std::string joinPtr(InputIterator start, InputIterator end, std::string delim = ",")
00076 {
00077 if (start == end) return "";
00078 std::ostringstream buffer;
00079 InputIterator current = start++;
00080 while (start != end) {
00081 buffer << **current << delim;
00082 current = start++;
00083 }
00084 buffer << **current;
00085 return buffer.str();
00086 }
00087
00097 std::vector<std::string> tokenize(const std::string& str, const std::string& delimiters = " ");
00098
00099
00103 std::string string2lowerCase(const std::string& str);
00104
00108 template<typename T>
00109 std::string type2string(T in) {
00110 std::ostringstream buffer;
00111 buffer << in;
00112 return buffer.str();
00113 }
00114
00118 template<>
00119 std::string type2string<double>(double in);
00120
00121
00122 template<typename T>
00123 T string2type(std::string s) {
00124 T retVal;
00125 std::stringstream buffer;
00126 buffer << s;
00127 buffer >> retVal;
00128 return retVal;
00129 }
00130
00131 typedef long epoch_seconds;
00136 epoch_seconds posixTime2epochTime(const boost::posix_time::ptime& time);
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 for (std::vector<std::string>::iterator tok = tokens.begin(); tok != tokens.end(); ++tok) {
00149 std::string current = trim(*tok);
00150 if (current == "...") {
00151 size_t currentPos = vals.size();
00152 if (currentPos < 2) {
00153 throw CDMException("tokenizeDotted: cannot use ... expansion at position " + type2string(currentPos-1) +", need at least two values before");
00154 }
00155 T last = vals[currentPos-1];
00156 T dist = last - vals[currentPos-2];
00157 T curVal = last + dist;
00158 if (++tok != tokens.end()) {
00159 T afterDotVal = string2type<T>(*tok);
00160
00161 while (fabs(static_cast<double>(curVal - afterDotVal)) > 1e-5) {
00162 vals.push_back(curVal);
00163 curVal += dist;
00164 }
00165
00166 vals.push_back(afterDotVal);
00167 }
00168 } else {
00169 T val = string2type<T>(current);
00170 vals.push_back(val);
00171 }
00172 }
00173 return vals;
00174 }
00175
00177 template<typename OUT>
00178 struct staticCast {
00179 template<typename IN>
00180 OUT operator()(const IN& in) { return static_cast<OUT>(in); }
00181 };
00182
00183
00187 template<typename IN, typename OUT>
00188 class ScaleValue : public std::unary_function<IN, OUT>
00189 {
00190 private:
00191 IN oldFill_;
00192 double oldScale_;
00193 double oldOffset_;
00194 OUT newFill_;
00195 double newScale_;
00196 double newOffset_;
00197 public:
00198 ScaleValue(double oldFill, double oldScale, double oldOffset, double newFill, double newScale, double newOffset) :
00199 oldFill_(static_cast<IN>(oldFill)), oldScale_(oldScale), oldOffset_(oldOffset),
00200 newFill_(static_cast<OUT>(newFill)), newScale_(newScale), newOffset_(newOffset) {}
00201 OUT operator()(const IN& in) const {
00202 if (in == oldFill_ || isinf(static_cast<double>(in))) {
00203 return newFill_;
00204 } else {
00205 return static_cast<OUT>(((oldScale_*in + oldOffset_)-newOffset_)/newScale_);
00206 }
00207 }
00208 };
00209
00213 template<typename IN, typename OUT>
00214 class ChangeMissingValue : public std::unary_function<IN, OUT>
00215 {
00216 private:
00217 IN oldFill_;
00218 OUT newFill_;
00219 public:
00220 ChangeMissingValue(double oldFill, double newFill) :
00221 oldFill_(static_cast<IN>(oldFill)), newFill_(static_cast<OUT>(newFill)) {}
00222 OUT operator()(const IN& in) const {
00223 if (in == oldFill_ || isinf(static_cast<double>(in))) {
00224 return newFill_;
00225 } else {
00226 return static_cast<OUT>(in);
00227 }
00228 }
00229 };
00230
00231 }
00232
00233 #endif