inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/waxml/ntuple
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines