]> git.jsancho.org Git - lugaru.git/blob - Source/logger/Copy of logger.cpp
First shot at crappy "streaming".
[lugaru.git] / Source / logger / Copy of logger.cpp
1 // ---------------------------------------------------------------------------------------------------------------------------------
2 //  _                                                  
3 // | |                                                 
4 // | | ___   __ _  __ _  ___ _ __      ___ _ __  _ __  
5 // | |/ _ \ / _` |/ _` |/ _ \ '__|    / __| '_ \| '_ \ 
6 // | | (_) | (_| | (_| |  __/ |    _ | (__| |_) | |_) |
7 // |_|\___/ \__, |\__, |\___|_|   (_) \___| .__/| .__/ 
8 //           __/ | __/ |                  | |   | |    
9 //          |___/ |___/                   |_|   |_|    
10 //
11 // Generic informational logging class
12 //
13 // ---------------------------------------------------------------------------------------------------------------------------------
14 //
15 // Restrictions & freedoms pertaining to usage and redistribution of this software:
16 //
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.
23 //
24 // For more information, visit HTTP://www.FluidStudios.com
25 //
26 // ---------------------------------------------------------------------------------------------------------------------------------
27 // Originally created on 07/06/2000 by Paul Nettle
28 //
29 // Copyright 2000, Fluid Studios, Inc., all rights reserved.
30 // ---------------------------------------------------------------------------------------------------------------------------------
31
32 //#include "stdafx.h" // If this line gives you an error, comment it out
33 #include <string>
34 #include <list>
35 #include <map>
36 #include <vector>
37 #include <iostream>
38 #include <fstream>
39 #include <iomanip>
40 //#include <strstream>
41 #include <sstream>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <ctime>
45 using namespace std;
46
47 #include "logger.h"
48
49 class LogFunc
50 {
51 public:
52         LogFunc(void) {}
53
54         void pushMessage(const std::string & str)
55         {
56                 entries.push_back(str);
57         }
58
59         void dump(std::ostream & os)
60         {
61                 std::list<std::string>::iterator it = entries.begin();
62                 for (; it != entries.end(); ++it)
63                 {
64                         os << *it;
65                 }
66         }
67
68 private:
69         std::list<std::string> entries;
70 };
71
72 class LogStack
73 {
74 public:
75         LogStack(void)
76         {
77                 pushFunc();
78         }
79
80         void pushFunc(void)
81         {
82                 entries.push_back(LogFunc());
83         }
84
85         void popFunc(void)
86         {
87                 if (entries.size() > 1)
88                 {
89                         entries.pop_back();
90                 }
91         }
92
93         void logMessage(const std::string & str_)
94         {
95                 entries.back().pushMessage(str_);
96         }
97
98         void dump(std::ostream & os)
99         {
100                 std::list<LogFunc>::iterator it = entries.begin();
101                 for (; it != entries.end(); ++it)
102                 {
103                         it->dump(os);
104                 }
105         }
106
107 private:
108         std::list<LogFunc> entries;
109 };
110
111 // ---------------------------------------------------------------------------------------------------------------------------------
112 // The global log stack object
113 // ---------------------------------------------------------------------------------------------------------------------------------
114 LogStack logStack;
115
116 void pushFunc(void) {logStack.pushFunc();}
117 void popFunc(void) {logStack.popFunc();}
118
119 void dumpLog(void)
120 {
121         ofstream of(logger.logFile().c_str(), ios::out | ios::trunc);
122         if (!of) return;
123         logStack.dump(of);
124 }
125
126 // ---------------------------------------------------------------------------------------------------------------------------------
127 // The global logger object
128 // ---------------------------------------------------------------------------------------------------------------------------------
129
130 Logger  logger;
131
132 // ---------------------------------------------------------------------------------------------------------------------------------
133 #ifdef _DEBUG
134 void    Logger::limitFileSize() const
135 {
136         if (fileSizeLimit() < 0) return;
137         struct  _stat sbuf;
138         _stat(logFile().c_str(), &sbuf);
139         if (sbuf.st_size > fileSizeLimit())
140         {
141                 unlink(logFile().c_str());
142         }
143 }
144
145 // ---------------------------------------------------------------------------------------------------------------------------------
146
147 void    Logger::start(const bool reset)
148 {
149         std::stringstream ss;
150
151         if (logStarted()) return;
152         _logStarted = true;
153
154         // Get the time
155
156         time_t  t = time(NULL);
157         string  ts = asctime(localtime(&t));
158         ts[ts.length() - 1] = 0;
159
160         // Start the log
161
162         //limitFileSize();
163         //ofstream of(logFile().c_str(), ios::out | (reset ? ios::trunc : ios::app));
164         //if (!of) return;
165
166         //of << "---------------------------------------------- Log begins on " << ts << " ----------------------------------------------" << endl;
167         ss << "---------------------------------------------- Log begins on " << ts << " ----------------------------------------------" << endl;
168         logStack.logMessage(ss.str());
169 }
170
171 // ---------------------------------------------------------------------------------------------------------------------------------
172
173 void    Logger::stop()
174 {
175         std::stringstream ss;
176
177         // Automatic One time only startup
178
179         if (!logStarted()) return;
180         _logStarted = false;
181
182         // Get the time
183
184         time_t  t = time(NULL);
185         string  ts = asctime(localtime(&t));
186         ts.erase(ts.length() - 1);
187
188         // Stop the log
189
190         limitFileSize();
191         ofstream of(logFile().c_str(), ios::out|ios::app);
192         if (!of) return;
193
194         //of << "----------------------------------------------- Log ends on " << ts << " -----------------------------------------------" << endl << endl;
195         ss << "----------------------------------------------- Log ends on " << ts << " -----------------------------------------------" << endl << endl;
196         logStack.logMessage(ss.str());
197 }
198
199 // ---------------------------------------------------------------------------------------------------------------------------------
200
201 void    Logger::logTex(const string &s, const LogFlags logBits)
202 {
203         std::stringstream ss;
204
205         // If the bits don't match the mask, then bail
206
207         if (!(logBits & logMask())) return;
208
209         // Open the file
210
211         limitFileSize();
212         ofstream of(logFile().c_str(), ios::out|ios::app);
213         if (!of) return;
214
215         // Output to the log file
216
217         //of << headerString(logBits) << s << endl;
218         ss << headerString(logBits) << s << endl;
219         logStack.logMessage(ss.str());
220 }
221
222 // ---------------------------------------------------------------------------------------------------------------------------------
223
224 void    Logger::logRaw(const string &s)
225 {
226         std::stringstream ss;
227
228         // Open the file
229
230         //limitFileSize();
231         //ofstream of(logFile().c_str(), ios::out|ios::app);
232         //if (!of) return;
233
234         // Log the output
235
236         //of << s << endl;
237         ss << s << endl;
238         logStack.logMessage(ss.str());
239 }
240
241 // ---------------------------------------------------------------------------------------------------------------------------------
242
243 void    Logger::logHex(const char *buffer, const unsigned int count, const LogFlags logBits)
244 {
245         std::stringstream ss;
246
247         // No input? No output
248
249         if (!buffer) return;
250
251         // If the bits don't match the mask, then bail
252
253         if (!(logBits & logMask())) return;
254
255         // Open the file
256
257         //limitFileSize();
258         //ofstream of(logFile().c_str(), ios::out|ios::app);
259         //if (!of) return;
260
261         // Log the output
262
263         unsigned int    logged = 0;
264         while(logged < count)
265         {
266                 // One line at a time...
267
268                 string          line;
269
270                 // The number of characters per line
271
272                 unsigned int    hexLength = 20;
273
274                 // Default the buffer
275
276                 unsigned int    i;
277                 for (i = 0; i < hexLength; i++)
278                 {
279                         line += "-- ";
280                 }
281
282                 for (i = 0; i < hexLength; i++)
283                 {
284                         line += ".";
285                 }
286
287                 // Fill it in with real data
288
289                 for (i = 0; i < hexLength && logged < count; i++, logged++)
290                 {
291                         unsigned char   byte = buffer[logged];
292                         unsigned int    index = i * 3;
293
294                         // The hex characters
295
296                         const string    hexlist("0123456789ABCDEF");
297                         line[index+0] = hexlist[byte >> 4];
298                         line[index+1] = hexlist[byte & 0xf];
299
300                         // The ascii characters
301
302                         if (byte < 0x20 || byte > 0x7f) byte = '.';
303                         line[(hexLength*3)+i+0] = byte;
304                 }
305
306                 // Write it to the log file
307
308                 //of << headerString(logBits) << line << endl;
309                 ss << headerString(logBits) << line << endl;
310                 logStack.logMessage(ss.str());
311         }
312 }
313
314 // ---------------------------------------------------------------------------------------------------------------------------------
315
316 void    Logger::indent(const string &s, const LogFlags logBits)
317 {
318         std::stringstream ss;
319
320         // If the bits don't match the mask, then bail
321
322         if (!(logBits & logMask())) return;
323
324         // Open the file
325
326         //limitFileSize();
327         //ofstream of(logFile().c_str(), ios::out|ios::app);
328         //if (!of) return;
329
330         // Log the output
331
332         //if (lineCharsFlag())  of << headerString(logBits) << "\xDA\xC4\xC4" << s << endl;
333         //else                  of << headerString(logBits) << "+-  " << s << endl;
334
335         if (lineCharsFlag())    ss << headerString(logBits) << "\xDA\xC4\xC4" << s << endl;
336         else                    ss << headerString(logBits) << "+-  " << s << endl;
337         logStack.logMessage(ss.str());
338
339         // Indent...
340
341         _indentCount += _indentChars;
342 }
343
344 // ---------------------------------------------------------------------------------------------------------------------------------
345
346 void    Logger::undent(const string &s, const LogFlags logBits)
347 {
348         std::stringstream ss;
349
350         // If the bits don't match the mask, then bail
351
352         if (!(logBits & logMask())) return;
353
354         // Undo the indentation
355
356         _indentCount -= _indentChars;
357         if (_indentCount < 0) _indentCount = 0;
358
359         // Open the file
360
361         limitFileSize();
362         ofstream of(logFile().c_str(), ios::out|ios::app);
363         if (!of) return;
364
365         // Log the output
366
367         //if (lineCharsFlag())  of << headerString(logBits) << "\xC0\xC4\xC4" << s << endl;
368         //else                  of << headerString(logBits) << "+-  " << s << endl;
369
370         if (lineCharsFlag())    ss << headerString(logBits) << "\xC0\xC4\xC4" << s << endl;
371         else                    ss << headerString(logBits) << "+-  " << s << endl;
372         logStack.logMessage(ss.str());
373 }
374
375 // ---------------------------------------------------------------------------------------------------------------------------------
376
377 const   string  &Logger::headerString(const LogFlags logBits) const
378 {
379         static  string  headerString;
380         headerString.erase();
381
382         // Get the string that represents the bits
383
384         switch(logBits)
385         {
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;
396         }
397
398         // File string (strip out the path)
399
400         char    temp[1024];
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;
405
406         // Time string (specially formatted to save room)
407
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;
412
413         // Spaces for indentation
414
415         memset(temp, ' ', sizeof(temp));
416         temp[_indentCount] = '\0';
417
418         // Add the indentation markers
419
420         int     count = 0;
421         while(count < _indentCount)
422         {
423                 if (lineCharsFlag())    temp[count] = '\xB3';
424                 else                    temp[count] = '|';
425                 count += _indentChars;
426         }
427         headerString += temp;
428
429         return headerString;
430 }
431
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*/){}
443 #endif
444
445 // ---------------------------------------------------------------------------------------------------------------------------------
446 // logger.cpp - End of file
447 // ---------------------------------------------------------------------------------------------------------------------------------
448