- Timestamp:
- 03/03/11 12:47:46 (14 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/Converter.cc
r10183 r10219 20 20 For example: 21 21 22 \code 22 23 Converter c(cout, "I:1;F:2;I:2", "COMMAND 1 2.5 4.2 3 4"); 24 \endcode 23 25 24 26 would produce a 20 byte data block with the integers 1, the floats … … 27 29 The opposite direction is also possible 28 30 29 Converter c(cout, "I:1;F:2;I:2", pointer, size); 31 \code 32 Converter c(cout, "I:1;F:2;I:2", pointer, size); 33 \endcode 34 35 In addition to converting the options from a string into binary format 36 or back all found values are also put into a vector of boost::any objects. 37 They can be accessed using e.g. 38 39 \code 40 Converter c(cout, "I:1;F:1;B:1;A:1;C", "112 5.5 on this is a test"); 41 42 cout << c.Get<int>(0) << endl; // prints '112' 43 cout << c.Get<float>(1) << endl; // prints '5.5' 44 cout << c.Get<bool>(2) << endl; // prints '1' 45 cout << c.Get<string>(3) << endl; // prints 'this' 46 cout << c.Get<string>(4) << endl; // prints 'is a test' 47 \endcode 48 49 The format parameter \b W(ord) is dedicated to this kind of conversion and 50 not understood by Dim. In addition there are \b O(ptions) which are like 51 Words but can be omitted. They should only be used at the end of the string. 52 \b B(ool) is also special. It evaluates true/false, yes/no, on/off, 1/0. 53 54 Access with Converter::Get() is exception safe. Access with Converter::At() 55 would throw an exception if the index is out of bounds or the conversion 56 fails. (This is the prefered method if the type is well known, to easily 57 detect programing faults) 30 58 31 59 @remark … … 39 67 #include <sstream> 40 68 69 #include <cctype> // std::tolower 70 #include <algorithm> // std::transform 71 41 72 #include <boost/regex.hpp> 42 73 … … 45 76 46 77 using namespace std; 78 79 template <class T> 80 void Converter::EvalImp(int i, std::stringstream &line, std::vector<char> &v, const T &val) 81 { 82 if (!line) 83 wout << " arg[" << i << "]"; 84 else 85 wout << " (" << val << ")"; 86 87 vec.push_back(val); 88 89 v.insert(v.end(), 90 reinterpret_cast<const char*>(&val), 91 reinterpret_cast<const char*>(&val+1)); 92 } 93 47 94 48 95 // -------------------------------------------------------------------------- … … 52 99 //! obtained it is set to 0. 53 100 //! 101 //! Adds the value to Converter::vec. 102 //! 54 103 //! @param i 55 104 //! The number of the processed argument (currently used for some debug … … 63 112 //! 64 113 template <class T> 65 void Converter::Eval(int i, std::stringstream &line, std::vector<char> &v ec) const66 { 67 T val = 0;114 void Converter::Eval(int i, std::stringstream &line, std::vector<char> &v) 115 { 116 T val; 68 117 line >> val; 69 if (!line) 70 wout << " arg[" << i << "]"; 118 119 EvalImp(i, line, v, val); 120 } 121 122 // -------------------------------------------------------------------------- 123 // 124 //! This functions works similar the the template Eval but is dedicated to 125 //! bools. It evaluates yes/no, on/off, true/false and 1/0. 126 //! 127 //! Sets the failbit of the stream if the "value" is not known. 128 //! 129 //! Adds the value to Converter::vec. 130 //! 131 //! @param line 132 //! The stringstream from which the data should be read 133 //! 134 //! @param vec 135 //! The vector of bytes at which end the data is added in binary format 136 //! 137 //! @returns 138 //! The bool evaluated 139 //! 140 void Converter::EvalBool(int i, std::stringstream &line, std::vector<char> &v) 141 { 142 string buf; 143 line >> buf; 144 transform(buf.begin(), buf.end(), buf.begin(), (int(*)(int)) std::tolower); 145 146 if (buf=="yes" || buf=="true" || buf=="on" || buf=="1") 147 { 148 EvalImp(i, line, v, bool(true)); 149 return; 150 } 151 152 if (buf=="no" || buf=="false" || buf=="off" || buf=="0") 153 { 154 EvalImp(i, line, v, bool(false)); 155 return; 156 } 157 158 line.clear(ios::failbit); 159 } 160 161 void Converter::EvalString(int i, std::stringstream &line, std::vector<char> &v) 162 { 163 while (line.peek()==' ') 164 line.get(); 165 166 string buf; 167 if (line.peek()=='\"') 168 { 169 line.get(); 170 getline(line, buf, '\"'); 171 } 71 172 else 72 wout << " (" << val << ")"; 73 74 vec.insert(vec.end(), 75 reinterpret_cast<char*>(&val), 76 reinterpret_cast<char*>(&val+1)); 173 line >> buf; 174 175 EvalImp(i, line, v, buf); 77 176 } 78 177 … … 121 220 122 221 // For better performance we could use sregex 123 static const boost::regex expr("^[ ]*([ CSILFDX])[ ]*(:[ ]*([1-9]+[0-9]*))?[ ]*$");222 static const boost::regex expr("^[ ]*([OBWCSILFDX])[ ]*(:[ ]*([1-9]+[0-9]*))?[ ]*$"); 124 223 125 224 // Tokenize the format … … 149 248 line.get(); 150 249 151 // Copy the string into the buffer 152 getline(line, buffer, '\0'); 153 154 wout << " (" << buffer << ")"; 155 data.insert(data.end(), buffer.begin(), buffer.end()); 250 line >> noskipws; 251 252 const istream_iterator<char> eol; // end-of-line iteartor 253 const string s(istream_iterator<char>(line), eol); 254 255 vec.push_back(s); 256 257 data.insert(data.end(), s.begin(), s.end()); 156 258 data.push_back(0); 259 260 line.clear(ios::eofbit); 261 157 262 continue; 158 263 } … … 172 277 line >> skipws; 173 278 break; 279 case 'B': EvalBool (arg++, line, data); break; 174 280 case 'S': Eval<short> (arg++, line, data); break; 175 281 case 'I': Eval<int> (arg++, line, data); break; … … 178 284 case 'D': Eval<double> (arg++, line, data); break; 179 285 case 'X': Eval<long long>(arg++, line, data); break; 286 case 'W': EvalString (arg++, line, data); break; 287 case 'O': EvalString (arg++, line, data); line.clear(ios::goodbit); break; 180 288 default: 181 289 // This should never happen! … … 183 291 break; 184 292 } 185 } 293 294 //wout << "{" << line.eof() << line.good() << line.fail() << "}"; 295 if (!line) 296 break; 297 } 298 //wout << "{" << line.eof() << line.good() << line.fail() << "}"; 186 299 187 300 wout << " [" << fmt << "]=" << data.size() << endl; … … 227 340 //! The pointer is increased accordingly. 228 341 //! 342 //! Adds the value to Converter::vec. 343 //! 229 344 //! @param ptr 230 345 //! A reference to a pointer to the data which should be converted. … … 235 350 //! 236 351 template<class T> 237 string Converter::Get(const char* &ptr) const 238 { 352 string Converter::Get(const char* &ptr) 353 { 354 const T &t = *reinterpret_cast<const T*>(ptr); 355 356 vec.push_back(t); 357 239 358 ostringstream stream; 240 stream << *reinterpret_cast<const T*>(ptr);359 stream << t; 241 360 ptr += sizeof(T); 242 361 … … 338 457 text << ' ' << str; 339 458 ptr += str.length()+1; 459 460 vec.push_back(str); 461 340 462 break; 341 463 } … … 379 501 data.push_back(0); 380 502 } 503 504 505 506 vector<string> Converter::Regex(const string &expr, const string &line) 507 { 508 const boost::regex reg(expr); 509 510 boost::smatch what; 511 if (!boost::regex_match(line, what, reg, boost::match_extra)) 512 return vector<string>(); 513 514 vector<string> ret; 515 for (unsigned int i=0; i<what.size(); i++) 516 ret.push_back(what[i]); 517 518 return ret; 519 } -
trunk/FACT++/src/Converter.h
r10183 r10219 5 5 #include <ostream> 6 6 7 #include <boost/any.hpp> 8 7 9 class Converter 8 10 { 9 11 private: 10 bool rc; 11 std::ostream &wout; 12 std::vector<char> data; 13 14 template<class V> 15 void Eval(int i, std::stringstream &line, std::vector<char> &vec) const; 12 bool rc; /// Flag for the success of the conversion 13 std::ostream &wout; /// ostream to which output is redirected 14 std::vector<char> data; /// data storage 15 std::vector<boost::any> vec; /// storage for typed data 16 16 17 17 template<class T> 18 std::string Get(const char *&data) const; 18 void EvalImp(int i, std::stringstream &line, std::vector<char> &v, const T &val); 19 template<class T> 20 void Eval(int i, std::stringstream &line, std::vector<char> &v); 21 void EvalBool(int i, std::stringstream &line, std::vector<char> &v); 22 void EvalString(int i, std::stringstream &line, std::vector<char> &v); 23 24 template<class T> 25 std::string Get(const char *&data); 19 26 20 27 public: … … 22 29 Converter(std::ostream &out, const std::string &fmt, const void *d, int size); 23 30 31 /// Returns whether the conversion was successfull 32 bool GetRc() const { return rc; } 33 34 /// const Pointer to the data memory 24 35 const char *Ptr() const { return &*data.begin(); } 36 /// non-const Pointer to the data memory (for convinience using Dim) 37 char *Ptr() { return &*data.begin(); } 38 39 /// Return the size of the data memory 40 int Size() const { return data.size(); } 41 42 /// Return the data memory converted into a string (not necessarily \0-terminated) 25 43 const std::string Str() const { return std::string(&*data.begin(), data.size()); } 26 char *Ptr() { return &*data.begin(); }27 int Size() const { return data.size(); }28 bool GetRc() const { return rc; }29 44 30 45 46 // Returns the number of entries in Converter:vec 47 int N() const { return vec.size(); } 48 49 /// Checks if an entry with the given class type is available at index i in Converter::vec 50 template <class T> 51 bool Has(unsigned int i) const { return i<vec.size() && vec[i].type()==typeid(T); } 52 53 /// return the entry with the given class type at index i from Converter::vec (exception safe) 54 template <class T> 55 T Get(int i) const { return !Has<T>(i) ? T() : boost::any_cast<T>(vec[i]); } 56 57 /// return the entry with the given class type at index i from Converter::vec (throws exceptions) 58 template <class T> 59 T At(int i) const { return boost::any_cast<T>(vec[i]); } 60 61 62 static std::vector<std::string> Regex(const std::string &expr, const std::string &line); 31 63 }; 32 64
Note:
See TracChangeset
for help on using the changeset viewer.