Index: trunk/FACT++/src/Converter.cc
===================================================================
--- trunk/FACT++/src/Converter.cc	(revision 10218)
+++ trunk/FACT++/src/Converter.cc	(revision 10219)
@@ -20,5 +20,7 @@
 For example:
 
+\code
   Converter c(cout, "I:1;F:2;I:2", "COMMAND 1 2.5 4.2 3 4");
+\endcode
 
 would produce a 20 byte data block with the integers 1, the floats
@@ -27,5 +29,31 @@
 The opposite direction is also possible
 
-  Converter c(cout, "I:1;F:2;I:2", pointer, size);
+\code
+   Converter c(cout, "I:1;F:2;I:2", pointer, size);
+ \endcode
+
+In addition to converting the options from a string into binary format
+or back all found values are also put into a vector of boost::any objects.
+They can be accessed using e.g.
+
+\code
+Converter c(cout, "I:1;F:1;B:1;A:1;C", "112 5.5 on this is a test");
+
+   cout << c.Get<int>(0)    << endl;  // prints '112'
+   cout << c.Get<float>(1)  << endl;  // prints '5.5'
+   cout << c.Get<bool>(2)   << endl;  // prints '1'
+   cout << c.Get<string>(3) << endl;  // prints 'this'
+   cout << c.Get<string>(4) << endl;  // prints 'is a test'
+\endcode
+
+The format parameter \b W(ord) is dedicated to this kind of conversion and
+not understood by Dim. In addition there are \b O(ptions) which are like
+Words but can be omitted. They should only be used at the end of the string.
+\b B(ool) is also special. It evaluates true/false, yes/no, on/off, 1/0.
+
+Access with Converter::Get() is exception safe. Access with Converter::At()
+would throw an exception if the index is out of bounds or the conversion
+fails. (This is the prefered method if the type is well known, to easily
+detect programing faults)
 
 @remark
@@ -39,4 +67,7 @@
 #include <sstream>
 
+#include <cctype>    // std::tolower
+#include <algorithm> // std::transform
+
 #include <boost/regex.hpp>
 
@@ -45,4 +76,20 @@
 
 using namespace std;
+
+template <class T>
+    void Converter::EvalImp(int i, std::stringstream &line, std::vector<char> &v, const T &val)
+{
+    if (!line)
+        wout << " arg[" << i << "]";
+    else
+        wout << " (" << val << ")";
+
+    vec.push_back(val);
+
+    v.insert(v.end(),
+             reinterpret_cast<const char*>(&val),
+             reinterpret_cast<const char*>(&val+1));
+}
+
 
 // --------------------------------------------------------------------------
@@ -52,4 +99,6 @@
 //! obtained it is set to 0.
 //!
+//! Adds the value to Converter::vec.
+//!
 //! @param i
 //!     The number of the processed argument (currently used for some debug
@@ -63,16 +112,66 @@
 //!
 template <class T>
-    void Converter::Eval(int i, std::stringstream &line, std::vector<char> &vec) const
-{
-    T val = 0;
+    void Converter::Eval(int i, std::stringstream &line, std::vector<char> &v)
+{
+    T val;
     line >> val;
-    if (!line)
-        wout << " arg[" << i << "]";
+
+    EvalImp(i, line, v, val);
+}
+
+// --------------------------------------------------------------------------
+//
+//! This functions works similar the the template Eval but is dedicated to
+//! bools. It evaluates yes/no, on/off, true/false and 1/0.
+//!
+//! Sets the failbit of the stream if the "value" is not known.
+//!
+//! Adds the value to Converter::vec.
+//!
+//! @param line
+//!     The stringstream from which the data should be read
+//!
+//! @param vec
+//!     The vector of bytes at which end the data is added in binary format
+//!
+//! @returns
+//!     The bool evaluated
+//!
+void Converter::EvalBool(int i, std::stringstream &line, std::vector<char> &v)
+{
+    string buf;
+    line >> buf;
+    transform(buf.begin(), buf.end(), buf.begin(), (int(*)(int)) std::tolower);
+
+    if (buf=="yes" || buf=="true" || buf=="on" || buf=="1")
+    {
+        EvalImp(i, line, v, bool(true));
+        return;
+    }
+
+    if (buf=="no" || buf=="false" || buf=="off" || buf=="0")
+    {
+        EvalImp(i, line, v, bool(false));
+        return;
+    }
+
+    line.clear(ios::failbit);
+}
+
+void Converter::EvalString(int i, std::stringstream &line, std::vector<char> &v)
+{
+    while (line.peek()==' ')
+        line.get();
+
+    string buf;
+    if (line.peek()=='\"')
+    {
+        line.get();
+        getline(line, buf, '\"');
+    }
     else
-        wout << " (" << val << ")";
-
-    vec.insert(vec.end(),
-               reinterpret_cast<char*>(&val),
-               reinterpret_cast<char*>(&val+1));
+        line >> buf;
+
+    EvalImp(i, line, v, buf);
 }
 
@@ -121,5 +220,5 @@
 
     // For better performance we could use sregex
-    static const boost::regex expr("^[ ]*([CSILFDX])[ ]*(:[ ]*([1-9]+[0-9]*))?[ ]*$");
+    static const boost::regex expr("^[ ]*([OBWCSILFDX])[ ]*(:[ ]*([1-9]+[0-9]*))?[ ]*$");
 
     // Tokenize the format
@@ -149,10 +248,16 @@
                 line.get();
 
-            // Copy the string into the buffer
-            getline(line, buffer, '\0');
-
-            wout << " (" << buffer << ")";
-            data.insert(data.end(), buffer.begin(), buffer.end());
+            line >> noskipws;
+
+            const istream_iterator<char> eol; // end-of-line iteartor
+            const string s(istream_iterator<char>(line), eol);
+
+            vec.push_back(s);
+
+            data.insert(data.end(), s.begin(), s.end());
             data.push_back(0);
+
+            line.clear(ios::eofbit);
+
             continue;
         }
@@ -172,4 +277,5 @@
                 line >> skipws;
                 break;
+            case 'B': EvalBool       (arg++, line, data); break;
             case 'S': Eval<short>    (arg++, line, data); break;
             case 'I': Eval<int>      (arg++, line, data); break;
@@ -178,4 +284,6 @@
             case 'D': Eval<double>   (arg++, line, data); break;
             case 'X': Eval<long long>(arg++, line, data); break;
+            case 'W': EvalString     (arg++, line, data); break;
+            case 'O': EvalString     (arg++, line, data); line.clear(ios::goodbit); break;
             default:
                 // This should never happen!
@@ -183,5 +291,10 @@
                 break;
             }
-    }
+
+        //wout << "{" << line.eof() << line.good() << line.fail() << "}";
+        if (!line)
+            break;
+    }
+    //wout << "{" << line.eof() << line.good() << line.fail() << "}";
 
     wout << " [" << fmt << "]=" << data.size() << endl;
@@ -227,4 +340,6 @@
 //! The pointer is increased accordingly.
 //!
+//! Adds the value to Converter::vec.
+//!
 //! @param ptr
 //!    A reference to a pointer to the data which should be converted.
@@ -235,8 +350,12 @@
 //!
 template<class T>
-string Converter::Get(const char* &ptr) const
-{
+string Converter::Get(const char* &ptr)
+{
+    const T &t = *reinterpret_cast<const T*>(ptr);
+
+    vec.push_back(t);
+
     ostringstream stream;
-    stream << *reinterpret_cast<const T*>(ptr);
+    stream << t;
     ptr += sizeof(T);
 
@@ -338,4 +457,7 @@
             text << ' ' << str;
             ptr += str.length()+1;
+
+            vec.push_back(str);
+
             break;
         }
@@ -379,2 +501,19 @@
     data.push_back(0);
 }
+
+
+
+vector<string> Converter::Regex(const string &expr, const string &line)
+{
+    const boost::regex reg(expr);
+
+    boost::smatch what;
+    if (!boost::regex_match(line, what, reg, boost::match_extra))
+        return vector<string>();
+
+    vector<string> ret;
+    for (unsigned int i=0; i<what.size(); i++)
+        ret.push_back(what[i]);
+
+    return ret;
+}
Index: trunk/FACT++/src/Converter.h
===================================================================
--- trunk/FACT++/src/Converter.h	(revision 10218)
+++ trunk/FACT++/src/Converter.h	(revision 10219)
@@ -5,16 +5,23 @@
 #include <ostream>
 
+#include <boost/any.hpp>
+
 class Converter
 {
 private:
-    bool rc;
-    std::ostream &wout;
-    std::vector<char> data;
-
-    template<class V>
-        void Eval(int i, std::stringstream &line, std::vector<char> &vec) const;
+    bool rc;                        /// Flag for the success of the conversion
+    std::ostream &wout;             /// ostream to which output is redirected
+    std::vector<char> data;         /// data storage
+    std::vector<boost::any> vec;    /// storage for typed data
 
     template<class T>
-        std::string Get(const char *&data) const;
+        void EvalImp(int i, std::stringstream &line, std::vector<char> &v, const T &val);
+    template<class T>
+        void Eval(int i, std::stringstream &line, std::vector<char> &v);
+        void EvalBool(int i, std::stringstream &line, std::vector<char> &v);
+        void EvalString(int i, std::stringstream &line, std::vector<char> &v);
+
+    template<class T>
+        std::string Get(const char *&data);
 
 public:
@@ -22,11 +29,36 @@
     Converter(std::ostream &out, const std::string &fmt, const void *d, int size);
 
+    /// Returns whether the conversion was successfull
+    bool GetRc() const { return rc; }
+
+    /// const Pointer to the data memory
     const char *Ptr() const { return &*data.begin(); }
+    /// non-const Pointer to the data memory (for convinience using Dim)
+    char *Ptr() { return &*data.begin(); }
+
+    /// Return the size of the data memory
+    int  Size() const { return data.size(); }
+
+    /// Return the data memory converted into a string (not necessarily \0-terminated)
     const std::string Str() const { return std::string(&*data.begin(), data.size()); }
-    char *Ptr() { return &*data.begin(); }
-    int   Size() const { return data.size(); }
-    bool  GetRc() const { return rc; }
 
 
+    // Returns the number of entries in Converter:vec
+    int N() const { return vec.size(); }
+
+    /// Checks if an entry with the given class type is available at index i in Converter::vec
+    template <class T>
+        bool Has(unsigned int i) const { return i<vec.size() && vec[i].type()==typeid(T); }
+
+    /// return the entry with the given class type at index i from Converter::vec (exception safe)
+    template <class T>
+        T Get(int i) const { return !Has<T>(i) ? T() : boost::any_cast<T>(vec[i]); }
+
+    /// return the entry with the given class type at index i from Converter::vec (throws exceptions)
+    template <class T>
+        T At(int i) const { return boost::any_cast<T>(vec[i]); }
+
+
+    static std::vector<std::string> Regex(const std::string &expr, const std::string &line);
 };
 
