logfile.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef LOGFILE_H
00003 #define LOGFILE_H
00004 
00005 #include <cstdio>
00006 #include <unistd.h>
00007 #include <map>
00008 #include <list>
00009 #include <string>
00010 #include <ctime>
00011 #include <iostream>
00012 #include <sstream>
00013 
00014 /// \ingroup baseclasses
00015 
00016 /**
00017    Logs values for arbitrary defined channels.
00018    T can be std::string or int or anything else supports the << of streams.
00019    (It is used as name for a channel.)
00020 */
00021 
00022 template <class T> class LogFile{
00023 protected:
00024     FILE* f;
00025     typedef std::map<T, double> data_map;
00026     typedef std::list<T> names_list;    
00027     data_map data;
00028     names_list names;
00029     std::string filename;
00030     std::string info;
00031     std::string separator;
00032     int line_counter;
00033     bool _print_names_list;
00034 public:
00035     LogFile(const std::string& filename="",const std::string& info="",const std::string& separator="\t")
00036         :filename(filename),info(info),separator(separator),line_counter(0),_print_names_list(false){
00037         f=NULL;
00038     };
00039     ~LogFile(){
00040         if(f)fclose(f);
00041     };
00042     void setInfo(const std::string& info){
00043         this->info=info;
00044     };
00045     void addChannel(const T& name){
00046         names.push_back(name);
00047     };
00048     void putData(const T& channel, double value){
00049         data[channel]=value;
00050     }; 
00051     /** print comment line in file 
00052         format is "#%d: %s"
00053     */
00054     void comment(const std::string& text){
00055         init();
00056         fprintf(f,"#%d: %s\n",line_counter,text.data());
00057         fflush(f);
00058     };
00059 
00060     /** print numbered names list in file header
00061     */
00062     void print_names_list(){
00063         _print_names_list=true;
00064     };
00065     /** print data line in file 
00066         format is "%5.3f%s" * number of channels
00067         %s is the separator string usually "\t"
00068     */
00069     void print(){
00070         if(names.empty())return;
00071         init();
00072         bool first=true;
00073         for(typename names_list::iterator i=names.begin();i!=names.end();++i){
00074             if(first) first=false;
00075             else fprintf(f,"%s",separator.data());
00076             fprintf(f,"%f", data[(*i)]);
00077         }
00078         fprintf(f,"\n");
00079         fflush(f);
00080         line_counter++;
00081     };
00082 protected:
00083     void init(){
00084         if(f!=NULL)return;
00085 
00086         time_t t=time(NULL);
00087         if(filename!="")        
00088             f=fopen(filename.data(),"w");
00089         else {
00090             char* time_str=ctime(&t);
00091             if(time_str[strlen(time_str)-1]='\n')
00092                 time_str[strlen(time_str)-1]='\0';
00093             f=fopen(time_str,"w");
00094         }
00095 
00096         bool first=true;
00097         // print info
00098         fprintf(f,"# created at %s",ctime(&t));
00099         fprintf(f,"#\n");
00100         fprintf(f,"#"); // insert comment char
00101         for(typename std::string::iterator s=info.begin();s!=info.end();++s){
00102             fprintf(f,"%c",*s);
00103             if(*s == '\n') // line ending found
00104                 fprintf(f,"#"); // insert comment char
00105         }
00106         fprintf(f,"#\n");
00107 
00108         // collect names
00109         std::ostringstream headline_str;
00110         std::ostringstream names_str;
00111         int counter=1;
00112         names_str << "# list of channels\n#\n";
00113         for(typename names_list::iterator i=names.begin();i!=names.end();++i,counter++){
00114             if(first) {
00115                 first=false;
00116                 headline_str << "#";
00117             } else 
00118                 headline_str << separator;
00119 
00120             headline_str << (*i);
00121             names_str << "#  " << counter << ": " << (*i) << std::endl;
00122         }       
00123         names_str << "#\n" << std::ends;
00124         headline_str << std::endl << std::ends;
00125         // print names list
00126         if(_print_names_list)
00127             fprintf(f,"%s",names_str.str().data());
00128         // print column headers
00129         fprintf(f,"%s",headline_str.str().data());
00130     }
00131 
00132 };
00133 
00134 #endif
00135 

Generated on Tue Apr 4 19:05:03 2006 for Robotsystem from Robot Group Leipzig by  doxygen 1.4.5