SPIN Framework
|
00001 // ----------------------------------------------------------------------------- 00002 // | ___ ___ _ _ _ ___ _ | 00003 // | / __>| . \| || \ | | __>_ _ ___ ._ _ _ ___ _ _ _ ___ _ _ | |__ | 00004 // | \__ \| _/| || | | _>| '_><_> || ' ' |/ ._>| | | |/ . \| '_>| / / | 00005 // | <___/|_| |_||_\_| |_| |_| <___||_|_|_|\___.|__/_/ \___/|_| |_\_\ | 00006 // | | 00007 // |---------------------------------------------------------------------------| 00008 // 00009 // http://spinframework.sourceforge.net 00010 // Copyright (C) 2009 Mike Wozniewski, Zack Settel 00011 // 00012 // Developed/Maintained by: 00013 // Mike Wozniewski (http://www.mikewoz.com) 00014 // Zack Settel (http://www.sheefa.net/zack) 00015 // 00016 // Principle Partners: 00017 // Shared Reality Lab, McGill University (http://www.cim.mcgill.ca/sre) 00018 // La Societe des Arts Technologiques (http://www.sat.qc.ca) 00019 // 00020 // Funding by: 00021 // NSERC/Canada Council for the Arts - New Media Initiative 00022 // Heritage Canada 00023 // Ministere du Developpement economique, de l'Innovation et de l'Exportation 00024 // 00025 // ----------------------------------------------------------------------------- 00026 // This file is part of the SPIN Framework. 00027 // 00028 // SPIN Framework is free software: you can redistribute it and/or modify 00029 // it under the terms of the GNU Lesser General Public License as published by 00030 // the Free Software Foundation, either version 3 of the License, or 00031 // (at your option) any later version. 00032 // 00033 // SPIN Framework is distributed in the hope that it will be useful, 00034 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00035 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00036 // GNU Lesser General Public License for more details. 00037 // 00038 // You should have received a copy of the GNU Lesser General Public License 00039 // along with SPIN Framework. If not, see <http://www.gnu.org/licenses/>. 00040 // ----------------------------------------------------------------------------- 00041 00042 #ifndef SPINLOGWX_H_ 00043 #define SPINLOGWX_H_ 00044 00045 #include <iostream> 00046 #include <fstream> 00047 #include <time.h> 00048 #include <stdio.h> 00049 00050 #include <wx/log.h> 00051 #include <wx/string.h> 00052 00053 // code from http://www.advogato.org/person/elanthis/diary/363.html 00054 00055 namespace spin 00056 { 00057 00058 00059 enum LogPriority 00060 { 00061 INFO, // regular unimportant log messages 00062 DEV, // debugging fluff 00063 ERROR, // it's dead, jim 00064 }; 00065 00066 class logbuf : public streambuf 00067 { 00068 00069 public: 00070 00071 // create a buffer and initialize our logfile 00072 logbuf(const char* logpath) : 00073 priority(INFO), buf(0), buflen(1024), bFILE(true), bCOUT(false) 00074 { 00075 // create our buffer 00076 buf = new char_type[buflen]; 00077 setp(buf, buf + buflen); 00078 00079 // open the log file 00080 logfile.open(logpath, ios::app); 00081 00082 if (!logfile.is_open()) 00083 { 00084 std::cout << "Error: Could not open log file: " << logpath << std::endl; 00085 exit(1); 00086 } 00087 00088 } 00089 00090 // free our buffer 00091 ~logbuf() 00092 { 00093 sync(); 00094 delete[] buf; 00095 } 00096 00097 // set the priority to be used on the next call to sync() 00098 void set_priority(LogPriority p) 00099 { 00100 priority = p; 00101 } 00102 00103 // logging modes: 00104 bool bCOUT; 00105 bool bFILE; 00106 bool bWXLG; 00107 00108 00109 private: 00110 00111 // spit out the time, priority, and the log buffer to cerr and logfile 00112 int sync() 00113 { 00114 // nifty time formatting functions from the C standard library 00115 time_t t = time(NULL); 00116 tm* tmp = localtime(&t); 00117 char shortTime[128]; 00118 char longTime[128]; 00119 strftime(shortTime, sizeof(shortTime), "%H:%M:%S", tmp); 00120 strftime(longTime, sizeof(longTime), "%Y-%m-%d %H:%M:%S", tmp); 00121 00122 // now we stream the time, then the priority, then the message 00123 if (bCOUT) std::cout << shortTime << ' '; 00124 if (bFILE) logfile << longTime << ' '; 00125 00126 switch (priority) 00127 { 00128 case INFO: 00129 if (bCOUT) std::cout << "[INFO:] "; 00130 if (bFILE) logfile << "[INFO:] "; 00131 break; 00132 case DEV: 00133 if (bCOUT) std::cout << "[DEBUG] "; 00134 if (bFILE) logfile << "[DEBUG] "; 00135 break; 00136 case ERROR: 00137 if (bCOUT) std::cout << "[ERROR] "; 00138 if (bFILE) logfile << "[ERROR] "; 00139 break; 00140 } 00141 00142 00143 if (bCOUT) std::cout.write(pbase(), pptr() - pbase()); 00144 if (bFILE) logfile.write(pbase(), pptr() - pbase()); 00145 00146 if (bWXLG) 00147 { 00148 char wxBuf[1024]; 00149 strncpy( wxBuf, pbase(), pptr()-pbase() ); 00150 wxBuf[pptr()-pbase()-1] = '\0'; // remove the \n that comes from std::endl 00151 wxLogMessage(wxString(wxBuf,wxConvUTF8)); 00152 } 00153 00154 // flush output 00155 if (bCOUT) std::cout.flush(); 00156 if (bFILE) logfile.flush(); 00157 00158 // reset our priority to INFO 00159 priority = INFO; 00160 00161 // reset the buffer 00162 setp(pbase(), epptr()); 00163 return 0; 00164 } 00165 00166 // we ran out of space, so grow the buffer 00167 int overflow(int c) 00168 { 00169 // allocate a new buffer and copy our current data into it, then swap 00170 // it with the old buffer 00171 char_type newbuf[buflen + 1024]; 00172 memcpy(newbuf, buf, buflen); 00173 delete[] buf; 00174 buf = newbuf; 00175 00176 // now we need to stuff c into the buffer 00177 sputc(c); 00178 return 0; 00179 } 00180 00181 // our log file 00182 ofstream logfile; 00183 00184 // current priority 00185 LogPriority priority; 00186 00187 // our buffer 00188 char_type* buf; 00189 unsigned long buflen; 00190 }; 00191 00192 00193 class spinLog : public std::ostream 00194 { 00195 00196 public: 00197 // we initialize the ostream to use our logbuf 00198 spinLog(const char* logpath) : std::ostream(new logbuf(logpath)) 00199 { 00200 buf = (logbuf*) rdbuf(); 00201 } 00202 00203 // set priority 00204 void set_priority(LogPriority pr) 00205 { 00206 buf->set_priority(pr); 00207 } 00208 00209 void enable_cout(bool b) 00210 { 00211 buf->bCOUT = b; 00212 } 00213 00214 void enable_logfile(bool b) 00215 { 00216 buf->bFILE = b; 00217 } 00218 00219 void enable_wxlog(bool b) 00220 { 00221 buf->bWXLG = b; 00222 } 00223 00224 00225 private: 00226 // our logbuf object 00227 logbuf *buf; 00228 }; 00229 00230 // set the priority for a spinLog/logbuf this must be a global function and not 00231 // a member to work around C++'s type resolution of overloaded functions 00232 static spinLog& operator<<(spinLog& vlog, LogPriority pr) 00233 { 00234 vlog.set_priority(pr); 00235 return vlog; 00236 } 00237 00238 } // end of namespace spin 00239 00240 00241 #endif