rllib  1
rlhistorylogger.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                        rlhistorylogger.cpp  -  description
00003                              -------------------
00004     begin                : Wed Dec 06 2006
00005     copyright            : (C) 2006 by Rainer Lehrig
00006     email                : lehrig@t-online.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as        *
00013  *   published by the Free Software Foundation                             *
00014  *                                                                         *
00015  ***************************************************************************/
00016 #include "rlhistorylogger.h"
00017 #include "rlcutil.h"
00018 #include <string.h>
00019 
00020 rlHistoryLogger::rlHistoryLogger(const char *csvName, int maxHoursPerFile, int maxLinesInMemory)
00021 {
00022   int val;
00023   debug = 0;
00024   first_line = current_line = NULL;
00025   fout = NULL;
00026   max_hours_per_file = maxHoursPerFile;
00027   if(max_hours_per_file <= 0) max_hours_per_file = 1;
00028   val = max_hours_per_file;
00029   time_diff.hour  = val % 24;
00030   val = val / 24;
00031   time_diff.day   = val % 31; // we are on the save side if we assume a month with 31 days
00032   val = val / 31;
00033   time_diff.month = val % 12;
00034   val = val / 12;
00035   time_diff.year  = val;
00036   max_lines_in_memory = maxLinesInMemory;
00037   if(max_lines_in_memory <= 0) max_lines_in_memory = 1;
00038   current_file = -1;
00039   csv_name = new char[strlen(csvName)+1];
00040   strcpy(csv_name,csvName);
00041   csv_file_name = new char[strlen(csvName)+132];
00042   time.getLocalTime();
00043   file_start_time.getLocalTime();
00044 }
00045 
00046 rlHistoryLogger::~rlHistoryLogger()
00047 {
00048   mutex.lock();
00049   if(fout != NULL) fclose(fout);
00050   delete [] csv_name;
00051   delete [] csv_file_name;
00052   if(first_line != NULL)
00053   {
00054     rlHistoryLogLine *last_line;
00055     current_line = first_line;
00056     while(current_line != NULL)
00057     {
00058       last_line = current_line;
00059       current_line = current_line->next;
00060       if(last_line != NULL)
00061       {
00062         delete [] last_line->line;
00063         delete last_line;
00064       }
00065     }
00066   }
00067   mutex.unlock();
00068 }
00069 
00070 int rlHistoryLogger::pushLine(const char *text)
00071 {
00072   mutex.lock();
00073   time.getLocalTime();
00074   char *line = new char[strlen(text)+132];
00075   sprintf(line,"%s\t%s",time.getTimeString(),text);
00076   if(debug) printf("pushLine=%s\n",line);
00077   pushLineToMemory(line);
00078   pushLineToFile(line);
00079   delete [] line;
00080   mutex.unlock();
00081   return 0;
00082 }
00083 
00084 int rlHistoryLogger::pushLineToMemory(const char *line)
00085 {
00086   rlHistoryLogLine *history_line;
00087 
00088   // put line at 1 position
00089   if(first_line == NULL)
00090   {
00091     first_line = new rlHistoryLogLine;
00092     first_line->line = new char[strlen(line)+1];
00093     strcpy(first_line->line,line);
00094     first_line->next = NULL;
00095   }
00096   else
00097   {
00098     history_line = first_line;
00099     first_line = new rlHistoryLogLine;
00100     first_line->line = new char[strlen(line)+1];
00101     strcpy(first_line->line,line);
00102     first_line->next = history_line;
00103   }
00104 
00105   // limit tail of list
00106   history_line = first_line;
00107   for(int i=0; i<max_lines_in_memory; i++)
00108   {
00109     if(history_line == NULL) break;
00110     history_line = history_line->next;
00111   }
00112   if(history_line != NULL)
00113   {
00114     rlHistoryLogLine *last_line;
00115     current_line = history_line->next;
00116     while(current_line != NULL)
00117     {
00118       last_line = current_line;
00119       current_line = current_line->next;
00120       if(last_line != NULL)
00121       {
00122         delete [] last_line->line;
00123         delete last_line;
00124       }
00125     }
00126     history_line->next = NULL;
00127   }
00128   return 0;
00129 }
00130 
00131 int rlHistoryLogger::pushLineToFile(const char *line)
00132 {
00133   if(fout == NULL) openFile();
00134   if((file_start_time + time_diff) < time)
00135   {
00136     if(fout != NULL) fclose(fout);
00137     fout = NULL;
00138     openFile();
00139   }
00140   if(fout != NULL)
00141   {
00142     fprintf(fout,"%s\n",line);
00143     fflush(fout);
00144   }
00145   return 0;
00146 }
00147 
00148 int rlHistoryLogger::openFile()
00149 {
00150   if(current_file == -1)
00151   {
00152     // find oldest file and open it for writing
00153     int i_oldest = 0;
00154     rlTime t,t_oldest;
00155     t_oldest.getLocalTime(); // this must be newer that any file time
00156     for(int i=0; i<10; i++)
00157     {
00158       sprintf(csv_file_name,"%s%d.csv",csv_name,i);
00159       if(t.getFileModificationTime(csv_file_name) == 0)
00160       {
00161         if(t < t_oldest) i_oldest = i;
00162       }
00163     }
00164     current_file = i_oldest;
00165     sprintf(csv_file_name,"%s%d.csv",csv_name,i_oldest);
00166     fout = fopen(csv_file_name,"w");
00167   }
00168   else
00169   {
00170     // open next file for writing
00171     current_file++;
00172     if(current_file >= 10) current_file = 0;
00173     sprintf(csv_file_name,"%s%d.csv",csv_name,current_file);
00174     fout = fopen(csv_file_name,"w");
00175   }
00176   file_start_time.getLocalTime();
00177   return 0;
00178 }
00179 
00180 const char *rlHistoryLogger::firstLine()
00181 {
00182   if(first_line == NULL) return "";
00183   current_line = first_line;
00184   return current_line->line;
00185 }
00186 
00187 const char *rlHistoryLogger::nextLine()
00188 {
00189   if(current_line == NULL) return "";
00190   current_line = current_line->next;
00191   if(current_line == NULL) return "";
00192   return current_line->line;
00193 }
00194 
00195 //#define TESTING_HISTORYLOGGER
00196 #ifdef TESTING_HISTORYLOGGER
00197 int main()
00198 {
00199   char text[1024];
00200   int val;
00201   rlHistoryLogger logger("test", 1);
00202   logger.debug = 1;
00203   val = 0;
00204   while(val >= 0)
00205   {
00206     if((val % 10) == 0)
00207     {
00208       const char *cptr;
00209       logger.mutex.lock();
00210       cptr = logger.firstLine();
00211       while(*cptr != '\0')
00212       {
00213         printf("mem=%s\n",cptr);
00214         cptr = logger.nextLine();
00215       }
00216       logger.mutex.unlock();
00217     }
00218     sprintf(text,"%d\t%d\t%d",val,val+1,val+2);
00219     logger.pushLine(text);
00220     val++;
00221     rlsleep(1000);
00222   }
00223   return 0;
00224 }
00225 #endif