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