1 // ---------------------------------------------------------------------------------------------------------------------------------
4 // | | ___ __ _ __ _ ___ _ __ ___ _ __ _ __
5 // | |/ _ \ / _` |/ _` |/ _ \ '__| / __| '_ \| '_ \
6 // | | (_) | (_| | (_| | __/ | _ | (__| |_) | |_) |
7 // |_|\___/ \__, |\__, |\___|_| (_) \___| .__/| .__/
11 // Generic informational logging class
13 // ---------------------------------------------------------------------------------------------------------------------------------
15 // Restrictions & freedoms pertaining to usage and redistribution of this software:
17 // * This software is 100% free
18 // * If you use this software (in part or in whole) you must credit the author.
19 // * This software may not be re-distributed (in part or in whole) in a modified
20 // form without clear documentation on how to obtain a copy of the original work.
21 // * You may not use this software to directly or indirectly cause harm to others.
22 // * This software is provided as-is and without warrantee. Use at your own risk.
24 // For more information, visit HTTP://www.FluidStudios.com
26 // ---------------------------------------------------------------------------------------------------------------------------------
27 // Originally created on 07/06/2000 by Paul Nettle
29 // Copyright 2000, Fluid Studios, Inc., all rights reserved.
30 // ---------------------------------------------------------------------------------------------------------------------------------
32 //#include "stdafx.h" // If this line gives you an error, comment it out
40 //#include <strstream>
42 #include <sys/types.h>
54 void pushMessage(const std::string & str)
56 entries.push_back(str);
59 void dump(std::ostream & os)
61 std::list<std::string>::iterator it = entries.begin();
62 for (; it != entries.end(); ++it)
69 std::list<std::string> entries;
82 entries.push_back(LogFunc());
87 if (entries.size() > 1)
93 void logMessage(const std::string & str_)
95 entries.back().pushMessage(str_);
98 void dump(std::ostream & os)
100 std::list<LogFunc>::iterator it = entries.begin();
101 for (; it != entries.end(); ++it)
108 std::list<LogFunc> entries;
111 // ---------------------------------------------------------------------------------------------------------------------------------
112 // The global log stack object
113 // ---------------------------------------------------------------------------------------------------------------------------------
116 void pushFunc(void) {logStack.pushFunc();}
117 void popFunc(void) {logStack.popFunc();}
121 ofstream of(logger.logFile().c_str(), ios::out | ios::trunc);
126 // ---------------------------------------------------------------------------------------------------------------------------------
127 // The global logger object
128 // ---------------------------------------------------------------------------------------------------------------------------------
132 // ---------------------------------------------------------------------------------------------------------------------------------
134 void Logger::limitFileSize() const
136 if (fileSizeLimit() < 0) return;
138 _stat(logFile().c_str(), &sbuf);
139 if (sbuf.st_size > fileSizeLimit())
141 unlink(logFile().c_str());
145 // ---------------------------------------------------------------------------------------------------------------------------------
147 void Logger::start(const bool reset)
149 std::stringstream ss;
151 if (logStarted()) return;
156 time_t t = time(NULL);
157 string ts = asctime(localtime(&t));
158 ts[ts.length() - 1] = 0;
163 //ofstream of(logFile().c_str(), ios::out | (reset ? ios::trunc : ios::app));
166 //of << "---------------------------------------------- Log begins on " << ts << " ----------------------------------------------" << endl;
167 ss << "---------------------------------------------- Log begins on " << ts << " ----------------------------------------------" << endl;
168 logStack.logMessage(ss.str());
171 // ---------------------------------------------------------------------------------------------------------------------------------
175 std::stringstream ss;
177 // Automatic One time only startup
179 if (!logStarted()) return;
184 time_t t = time(NULL);
185 string ts = asctime(localtime(&t));
186 ts.erase(ts.length() - 1);
191 ofstream of(logFile().c_str(), ios::out|ios::app);
194 //of << "----------------------------------------------- Log ends on " << ts << " -----------------------------------------------" << endl << endl;
195 ss << "----------------------------------------------- Log ends on " << ts << " -----------------------------------------------" << endl << endl;
196 logStack.logMessage(ss.str());
199 // ---------------------------------------------------------------------------------------------------------------------------------
201 void Logger::logTex(const string &s, const LogFlags logBits)
203 std::stringstream ss;
205 // If the bits don't match the mask, then bail
207 if (!(logBits & logMask())) return;
212 ofstream of(logFile().c_str(), ios::out|ios::app);
215 // Output to the log file
217 //of << headerString(logBits) << s << endl;
218 ss << headerString(logBits) << s << endl;
219 logStack.logMessage(ss.str());
222 // ---------------------------------------------------------------------------------------------------------------------------------
224 void Logger::logRaw(const string &s)
226 std::stringstream ss;
231 //ofstream of(logFile().c_str(), ios::out|ios::app);
238 logStack.logMessage(ss.str());
241 // ---------------------------------------------------------------------------------------------------------------------------------
243 void Logger::logHex(const char *buffer, const unsigned int count, const LogFlags logBits)
245 std::stringstream ss;
247 // No input? No output
251 // If the bits don't match the mask, then bail
253 if (!(logBits & logMask())) return;
258 //ofstream of(logFile().c_str(), ios::out|ios::app);
263 unsigned int logged = 0;
264 while(logged < count)
266 // One line at a time...
270 // The number of characters per line
272 unsigned int hexLength = 20;
274 // Default the buffer
277 for (i = 0; i < hexLength; i++)
282 for (i = 0; i < hexLength; i++)
287 // Fill it in with real data
289 for (i = 0; i < hexLength && logged < count; i++, logged++)
291 unsigned char byte = buffer[logged];
292 unsigned int index = i * 3;
294 // The hex characters
296 const string hexlist("0123456789ABCDEF");
297 line[index+0] = hexlist[byte >> 4];
298 line[index+1] = hexlist[byte & 0xf];
300 // The ascii characters
302 if (byte < 0x20 || byte > 0x7f) byte = '.';
303 line[(hexLength*3)+i+0] = byte;
306 // Write it to the log file
308 //of << headerString(logBits) << line << endl;
309 ss << headerString(logBits) << line << endl;
310 logStack.logMessage(ss.str());
314 // ---------------------------------------------------------------------------------------------------------------------------------
316 void Logger::indent(const string &s, const LogFlags logBits)
318 std::stringstream ss;
320 // If the bits don't match the mask, then bail
322 if (!(logBits & logMask())) return;
327 //ofstream of(logFile().c_str(), ios::out|ios::app);
332 //if (lineCharsFlag()) of << headerString(logBits) << "\xDA\xC4\xC4" << s << endl;
333 //else of << headerString(logBits) << "+- " << s << endl;
335 if (lineCharsFlag()) ss << headerString(logBits) << "\xDA\xC4\xC4" << s << endl;
336 else ss << headerString(logBits) << "+- " << s << endl;
337 logStack.logMessage(ss.str());
341 _indentCount += _indentChars;
344 // ---------------------------------------------------------------------------------------------------------------------------------
346 void Logger::undent(const string &s, const LogFlags logBits)
348 std::stringstream ss;
350 // If the bits don't match the mask, then bail
352 if (!(logBits & logMask())) return;
354 // Undo the indentation
356 _indentCount -= _indentChars;
357 if (_indentCount < 0) _indentCount = 0;
362 ofstream of(logFile().c_str(), ios::out|ios::app);
367 //if (lineCharsFlag()) of << headerString(logBits) << "\xC0\xC4\xC4" << s << endl;
368 //else of << headerString(logBits) << "+- " << s << endl;
370 if (lineCharsFlag()) ss << headerString(logBits) << "\xC0\xC4\xC4" << s << endl;
371 else ss << headerString(logBits) << "+- " << s << endl;
372 logStack.logMessage(ss.str());
375 // ---------------------------------------------------------------------------------------------------------------------------------
377 const string &Logger::headerString(const LogFlags logBits) const
379 static string headerString;
380 headerString.erase();
382 // Get the string that represents the bits
386 case LOG_INDENT : headerString += "> "; break;
387 case LOG_UNDENT : headerString += "< "; break;
388 case LOG_ALL : headerString += "A "; break;
389 case LOG_CRIT : headerString += "! "; break;
390 case LOG_DATA : headerString += "D "; break;
391 case LOG_ERR : headerString += "E "; break;
392 case LOG_FLOW : headerString += "F "; break;
393 case LOG_INFO : headerString += "I "; break;
394 case LOG_WARN : headerString += "W "; break;
395 default: headerString += " "; break;
398 // File string (strip out the path)
401 int ix = sourceFile().rfind('\\');
402 ix = (ix == (int) string::npos ? 0: ix+1);
403 sprintf(temp, "%25s[%04d]", sourceFile().substr(ix).c_str(), sourceLine());
404 headerString += temp;
406 // Time string (specially formatted to save room)
408 time_t t = time(NULL);
409 struct tm *tme = localtime(&t);
410 sprintf(temp, "%02d/%02d %02d:%02d ", tme->tm_mon + 1, tme->tm_mday, tme->tm_hour, tme->tm_min);
411 headerString += temp;
413 // Spaces for indentation
415 memset(temp, ' ', sizeof(temp));
416 temp[_indentCount] = '\0';
418 // Add the indentation markers
421 while(count < _indentCount)
423 if (lineCharsFlag()) temp[count] = '\xB3';
424 else temp[count] = '|';
425 count += _indentChars;
427 headerString += temp;
432 #else /*Release Build*/
433 std::string release_Null;
434 void Logger::limitFileSize() const {}
435 const string &Logger::headerString(const LogFlags logBits) const{return release_Null;}
436 void Logger::start(const bool reset){}
437 void Logger::stop(){}
438 void Logger::logTex(const string &s, const LogFlags logBits /*= LOG_INFO*/){}
439 void Logger::logRaw(const string &s){}
440 void Logger::logHex(const char *buffer, const unsigned int count, const LogFlags logBits /*= LOG_INFO*/){}
441 void Logger::indent(const string &s, const LogFlags logBits /*= LOG_INDENT*/){}
442 void Logger::undent(const string &s, const LogFlags logBits /*= LOG_UNDENT*/){}
445 // ---------------------------------------------------------------------------------------------------------------------------------
446 // logger.cpp - End of file
447 // ---------------------------------------------------------------------------------------------------------------------------------