Go to the documentation of this file.00001 #include "csvoutput.hh"
00002 #include "value.hh"
00003 #include "typevisitor.hh"
00004 #include <boost/lexical_cast.hpp>
00005 #include <boost/algorithm/string/join.hpp>
00006
00007 using namespace Typelib;
00008 using namespace std;
00009
00010 namespace
00011 {
00012 using namespace Typelib;
00013 using namespace std;
00014 using boost::join;
00015 class HeaderVisitor : public TypeVisitor
00016 {
00017 list<string> m_name;
00018 list<string> m_headers;
00019
00020 protected:
00021 void output()
00022 {
00023 string name = join(m_name, "");
00024 m_headers.push_back(name);
00025 }
00026
00027 bool visit_ (OpaqueType const& type) { output(); return true; }
00028 bool visit_ (Numeric const&) { output(); return true; }
00029 bool visit_ (Enum const&) { output(); return true; }
00030
00031 bool visit_ (Pointer const& type)
00032 {
00033 m_name.push_front("*(");
00034 m_name.push_back(")");
00035 TypeVisitor::visit_(type);
00036 m_name.pop_front();
00037 m_name.pop_back();
00038 return true;
00039 }
00040 bool visit_ (Array const& type)
00041 {
00042 m_name.push_back("[");
00043 m_name.push_back("");
00044 m_name.push_back("]");
00045 list<string>::iterator count = m_name.end();
00046 --(--count);
00047 for (size_t i = 0; i < type.getDimension(); ++i)
00048 {
00049 *count = boost::lexical_cast<string>(i);
00050 TypeVisitor::visit_(type);
00051 }
00052 m_name.pop_back();
00053 m_name.pop_back();
00054 m_name.pop_back();
00055 return true;
00056 }
00057
00058 bool visit_ (Compound const& type)
00059 {
00060 m_name.push_back(".");
00061 TypeVisitor::visit_(type);
00062 m_name.pop_back();
00063 return true;
00064 }
00065 bool visit_ (Compound const& type, Field const& field)
00066 {
00067 m_name.push_back(field.getName());
00068 TypeVisitor::visit_(type, field);
00069 m_name.pop_back();
00070 return true;
00071 }
00072
00073 using TypeVisitor::visit_;
00074 public:
00075 list<string> apply(Type const& type, std::string const& basename)
00076 {
00077 m_headers.clear();
00078 m_name.clear();
00079 m_name.push_back(basename);
00080 TypeVisitor::apply(type);
00081 return m_headers;
00082 }
00083 };
00084
00085 class LineVisitor : public ValueVisitor
00086 {
00087 list<string> m_output;
00088 bool m_char_as_numeric;
00089
00090 protected:
00091 template<typename T>
00092 bool display(T value)
00093 {
00094 m_output.push_back(boost::lexical_cast<string>(value));
00095 return true;
00096 }
00097 using ValueVisitor::visit_;
00098 bool visit_ (Value value, OpaqueType const& type)
00099 {
00100 display("<" + type.getName() + ">");
00101 return true;
00102 }
00103 bool visit_ (int8_t & value)
00104 {
00105 if (m_char_as_numeric)
00106 return display<int>(value);
00107 else
00108 return display(value);
00109 }
00110 bool visit_ (uint8_t & value)
00111 {
00112 if (m_char_as_numeric)
00113 return display<int>(value);
00114 else
00115 return display(value);
00116 }
00117 bool visit_ (int16_t & value) { return display(value); }
00118 bool visit_ (uint16_t& value) { return display(value); }
00119 bool visit_ (int32_t & value) { return display(value); }
00120 bool visit_ (uint32_t& value) { return display(value); }
00121 bool visit_ (int64_t & value) { return display(value); }
00122 bool visit_ (uint64_t& value) { return display(value); }
00123 bool visit_ (float & value) { return display(value); }
00124 bool visit_ (double & value) { return display(value); }
00125 bool visit_ (Enum::integral_type& v, Enum const& e)
00126 {
00127 try { m_output.push_back(e.get(v)); }
00128 catch(Typelib::Enum::ValueNotFound)
00129 { display(v); }
00130 return true;
00131 }
00132
00133 public:
00134 list<string> apply(Value const& value, bool char_as_numeric)
00135 {
00136 m_output.clear();
00137 m_char_as_numeric = char_as_numeric;
00138 ValueVisitor::apply(value);
00139 return m_output;
00140 }
00141 };
00142 }
00143
00144
00145 CSVOutput::CSVOutput(Type const& type, std::string const& sep, bool char_as_numeric = true)
00146 : m_type(type), m_separator(sep), m_char_as_numeric(char_as_numeric) {}
00147
00149 void CSVOutput::header(std::ostream& out, std::string const& basename)
00150 {
00151 HeaderVisitor visitor;
00152 out << join(visitor.apply(m_type, basename), m_separator);
00153 }
00154
00155 void CSVOutput::display(std::ostream& out, void* value)
00156 {
00157 LineVisitor visitor;
00158 out << join(visitor.apply( Value(value, m_type), m_char_as_numeric ), m_separator );
00159 }
00160