inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_waxml_ntuple 00005 #define inlib_waxml_ntuple 00006 00007 // A ntuple class to write at the aida tuple format. 00008 // Each add_row() write a row at the aida tuple format. 00009 00010 #include "../vfind" 00011 #include "../vmanip" 00012 #include "../sout" 00013 #include "../tos" 00014 00015 #include <ostream> 00016 00017 // for sub_ntuple : 00018 #include "../scast" 00019 #include <sstream> 00020 00021 namespace inlib { 00022 namespace waxml { 00023 00024 class ntuple { 00025 protected: 00026 static cid _cid(int) {return 1;} 00027 static cid _cid(float) {return 2;} 00028 static cid _cid(double) {return 3;} 00029 00030 class iobj { 00031 public: 00032 virtual ~iobj(){} 00033 public: 00034 virtual void* cast(cid) const = 0; 00035 virtual const std::string& name() const = 0; 00036 virtual std::string aida_type() const = 0; 00037 }; 00038 00039 class leaf : public virtual iobj { 00040 public: 00041 static cid id_class() {return 100;} 00042 public: //iobj 00043 virtual void* cast(cid a_class) const { 00044 if(void* p = cmp_cast<leaf>(this,a_class)) {return p;} 00045 else return 0; 00046 } 00047 public: 00048 virtual std::string s_def() const = 0; 00049 virtual std::string s_value() const = 0; 00050 public: 00051 leaf(){} 00052 virtual ~leaf(){} 00053 leaf(const leaf& a_from):iobj(a_from){} 00054 leaf& operator=(const leaf&){return *this;} 00055 }; 00056 00057 static const std::string& s_aida_type(int) { 00058 static const std::string s_v("int"); 00059 return s_v; 00060 } 00061 static const std::string& s_aida_type(float) { 00062 static const std::string s_v("float"); 00063 return s_v; 00064 } 00065 static const std::string& s_aida_type(double) { 00066 static const std::string s_v("double"); 00067 return s_v; 00068 } 00069 00070 public: 00071 template <class T> 00072 class column : public leaf { 00073 public: 00074 static cid id_class() {return 200+_cid(T());} 00075 public: //iobj 00076 virtual void* cast(cid a_class) const { 00077 if(void* p = cmp_cast< column<T> >(this,a_class)) {return p;} 00078 else return leaf::cast(a_class); 00079 } 00080 virtual const std::string& name() const {return m_name;} 00081 virtual std::string aida_type() const {return s_aida_type(T());} 00082 public: //leaf 00083 virtual std::string s_def() const {return tos(m_def);} 00084 virtual std::string s_value() const {return tos(m_tmp);} 00085 public: 00086 column(const std::string& a_name,const T& a_def) 00087 :m_name(a_name),m_def(a_def),m_tmp(a_def) 00088 {} 00089 virtual ~column(){} 00090 protected: 00091 column(const column& a_from) 00092 :leaf(a_from) 00093 ,m_name(a_from.m_name) 00094 ,m_def(a_from.m_def) 00095 ,m_tmp(a_from.m_tmp) 00096 {} 00097 column& operator=(const column& a_from){ 00098 m_name = a_from.m_name; 00099 m_def = a_from.m_def; 00100 m_tmp = a_from.m_tmp; 00101 return *this; 00102 } 00103 public: 00104 bool fill(const T& a_value) {m_tmp = a_value;return true;} 00105 protected: 00106 std::string m_name; 00107 T m_def; 00108 T m_tmp; 00109 }; 00110 00111 00112 class sub_ntuple : public virtual iobj { 00113 public: 00114 static cid id_class() {return 300;} 00115 public: //iobj 00116 virtual void* cast(cid a_class) const { 00117 if(void* p = cmp_cast<sub_ntuple>(this,a_class)) {return p;} 00118 else return 0; 00119 } 00120 virtual const std::string& name() const {return m_name;} 00121 virtual std::string aida_type() const {return "ITuple";} 00122 public: 00123 sub_ntuple(const std::string& a_name, 00124 const std::string& a_spaces) 00125 :m_name(a_name),m_spaces(a_spaces){} 00126 virtual ~sub_ntuple(){} 00127 protected: 00128 sub_ntuple(const sub_ntuple& a_from) 00129 :iobj(a_from),m_name(a_from.m_name){} 00130 sub_ntuple& operator=(const sub_ntuple&){return *this;} 00131 public: 00132 template <class T> 00133 column<T>* create_column(const std::string& a_name, 00134 const T& a_def = T()) { 00135 if(find_named<iobj>(m_cols,a_name)) return 0; 00136 column<T>* col = new column<T>(a_name,a_def); 00137 if(!col) return 0; 00138 m_cols.push_back(col); 00139 return col; 00140 } 00141 00142 sub_ntuple* create_sub_ntuple(const std::string& a_name){ 00143 if(find_named<iobj>(m_cols,a_name)) return 0; 00144 std::string spaces; 00145 for(unsigned int i=0;i<4;i++) spaces += " "; 00146 sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces); 00147 if(!col) return 0; 00148 m_cols.push_back(col); 00149 return col; 00150 } 00151 00152 00153 const std::vector<iobj*>& columns() const {return m_cols;} 00154 00155 std::string booking() const { 00156 std::string s; 00157 get_booking(m_cols,s); 00158 return s; 00159 } 00160 void reset() {m_tmp.clear();} 00161 const std::string& value() const {return m_tmp;} 00162 00163 bool add_row() { 00164 if(m_cols.empty()) return false; 00165 std::ostringstream sout; 00166 sout << m_spaces << "<row>" << std::endl; 00167 std::vector<iobj*>::const_iterator it; 00168 for(it=m_cols.begin();it!=m_cols.end();++it) { 00169 if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))) { 00170 sout << m_spaces << " <entryITuple>" << std::endl; 00171 sout << sub->value(); 00172 sout << m_spaces << " </entryITuple>" << std::endl; 00173 sub->reset(); 00174 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){ 00175 sout << m_spaces << " <entry" 00176 << " value=\"" << lf->s_value().c_str() 00177 << "\"/>" << std::endl; 00178 } 00179 } 00180 sout << m_spaces << "</row>" << std::endl; 00181 00182 m_tmp += sout.str(); 00183 00184 return true; 00185 } 00186 protected: 00187 std::string m_name; 00188 std::string m_spaces; 00189 std::vector<iobj*> m_cols; 00190 std::string m_tmp; 00191 }; 00192 00193 public: 00194 ntuple(std::ostream& a_writer, 00195 unsigned int a_spaces = 0) 00196 :m_writer(a_writer){ 00197 for(unsigned int i=0;i<a_spaces;i++) m_spaces += " "; 00198 } 00199 virtual ~ntuple() { 00200 inlib::clear<iobj>(m_cols); 00201 } 00202 protected: 00203 ntuple(const ntuple& a_from) 00204 :m_writer(a_from.m_writer) 00205 ,m_spaces(a_from.m_spaces) 00206 {} 00207 ntuple& operator=(const ntuple& a_from){ 00208 m_spaces = a_from.m_spaces; 00209 return *this; 00210 } 00211 public: 00212 const std::vector<iobj*>& columns() const {return m_cols;} 00213 00214 template <class T> 00215 column<T>* create_column(const std::string& a_name, 00216 const T& a_def = T()) { 00217 if(find_named<iobj>(m_cols,a_name)) return 0; 00218 column<T>* col = new column<T>(a_name,a_def); 00219 if(!col) return 0; 00220 m_cols.push_back(col); 00221 return col; 00222 } 00223 00224 sub_ntuple* create_sub_ntuple(const std::string& a_name){ 00225 if(find_named<iobj>(m_cols,a_name)) return 0; 00226 std::string spaces; 00227 for(unsigned int i=0;i<10;i++) spaces += " "; 00228 sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces); 00229 if(!col) return 0; 00230 m_cols.push_back(col); 00231 return col; 00232 } 00233 00234 void write_header(const std::string& a_path, 00235 const std::string& a_name, 00236 const std::string& a_title){ 00237 00238 // <tuple> : 00239 m_writer << m_spaces << " <tuple" 00240 << " path=" << sout(a_path) 00241 << " name=" << sout(a_name) 00242 << " title=" << sout(a_title) 00243 << ">" << std::endl; 00244 00245 // <columns> : 00246 m_writer << m_spaces << " <columns>" << std::endl; 00247 00248 std::vector<iobj*>::iterator it; 00249 for(it=m_cols.begin();it!=m_cols.end();++it) { 00250 if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){ 00251 m_writer << m_spaces << " <column" 00252 << " name=" << sout((*it)->name()) 00253 << " type=" << sout("ITuple") 00254 << " booking=" << sout(sub->booking()) 00255 << "/>" << std::endl; 00256 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){ 00257 m_writer << m_spaces << " <column" 00258 << " name=" << sout((*it)->name()) 00259 << " type=" << sout((*it)->aida_type()) 00260 << " default=" << sout(lf->s_def()) 00261 << "/>" << std::endl; 00262 } 00263 } 00264 00265 m_writer << m_spaces << " </columns>" << std::endl; 00266 00267 // rows : 00268 m_writer << m_spaces << " <rows>" << std::endl; 00269 } 00270 00271 bool add_row() { 00272 if(m_cols.empty()) return false; 00273 m_writer << m_spaces << " <row>" << std::endl; 00274 std::vector<iobj*>::const_iterator it; 00275 for(it=m_cols.begin();it!=m_cols.end();++it) { 00276 if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){ 00277 m_writer << m_spaces << " <entryITuple>" << std::endl; 00278 m_writer << sub->value(); 00279 m_writer << m_spaces << " </entryITuple>" << std::endl; 00280 sub->reset(); 00281 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){ 00282 m_writer << m_spaces << " <entry" 00283 << " value=" << sout(lf->s_value()) 00284 << "/>" << std::endl; 00285 } 00286 } 00287 m_writer << m_spaces << " </row>" << std::endl; 00288 return true; 00289 } 00290 00291 void write_trailer() { 00292 m_writer << m_spaces << " </rows>" << std::endl; 00293 m_writer << m_spaces << " </tuple>" << std::endl; 00294 } 00295 00296 protected: 00297 static void get_booking(const std::vector<iobj*>& a_cols, 00298 std::string& a_string) { 00299 a_string += "{"; //we need the + because of the tuple in tuple. 00300 00301 std::vector<iobj*>::const_iterator it; 00302 for(it=a_cols.begin();it!=a_cols.end();++it) { 00303 if(it!=a_cols.begin()) a_string += ","; 00304 00305 std::string type = (*it)->aida_type(); 00306 a_string += type + " "; 00307 std::string name = (*it)->name(); 00308 a_string += name + " = "; 00309 00310 if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){ 00311 get_booking(sub->columns(),a_string); 00312 } else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){ 00313 a_string += lf->s_def(); 00314 } 00315 } 00316 a_string += "}"; 00317 } 00318 00319 protected: 00320 std::ostream& m_writer; 00321 std::string m_path; 00322 std::string m_name; 00323 std::string m_title; 00324 std::string m_spaces; 00325 std::vector<iobj*> m_cols; 00326 }; 00327 00328 }} 00329 00330 #endif