3 removed files
slic/include
diff -N logstream.h
--- logstream.h 13 Oct 2005 23:52:11 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,190 +0,0 @@
-// ======================================================================================
-// logstream.h - Version 1.0 - Copyright ©2002 Stephen W. Chappell
-// A customized output stream for logging data
-//
-// Namespace: slug
-//
-// Requires: streamext.h
-//
-// Contents:
-// - logbuf - a filtering streambuf used with the logstream; it inserts the date,
-// time, and log level into the real buffer
-// - log_base - a base class for the logstream; it contains members needed to
-// initialize the other logstream base, ostream, as well as a workaround
-// for not being able to cast rdbuf() is MSVC
-// - logstream - an ostream descendent that uses the filtering logbuf to output data
-//
-// Description:
-// This customized ostream descendant extends the ostream class using standard (but
-// somewhat cryptic) methods. The logstream itself is simply an ostream descendant that
-// utilizes a custom streambuf. The custom streambuf (logbuf, a streambuf descendant)
-// is what really does the work:
-//
-// - the logbuf filters the data going to some other streambuf or streambuf descendant,
-// essentially looking for newlines so it can insert some stuff in the beginning
-// - the other streambuf does its normal thing to output data; it's supplied to the
-// logbuf constructor as a parameter
-//
-// This might seem complicated, but since the streambuf is what really does all the
-// work in standard iostreams, this makes a whole lot of sense, and, now that it's
-// done, it seems a whole lot less complicated
-//
-// For the moment, log_base contains a std::filebuf to use to actually output the data,
-// at some point it would be nice to make this a parameter so that, for example, some
-// sort of remote window logging or multithreaded logging could be implemented with
-// another custom streambuf (the logbuf itself shouldn't have to change)
-//
-// Additional credits:
-// - the basic class architecture was strongly influenced by the iostreams postings of
-// Dietmar Kühl regarding "prefix" streams at
-// http://www.inf.uni-konstanz.de/~kuehl/c++/iostream/
-//
-// Revision History:
-// Date | Ver | Author | Description
-// -----------+-----+--------+--------------------------------------------------------
-// 01/14/2002 | 1.0 | SwC | Initial Version
-// ======================================================================================
-#ifndef SLUG_LOGSTREAM_H
-#define SLUG_LOGSTREAM_H
-
-#include <fstream>
-#include <ostream>
-#include <streambuf>
-
-// ======================================================================================
-
-namespace slug
-{
-
-// ======================================================================================
-// Class Declarations
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// class logbuf - this is a "filtering" streambuf; it filters data destined for the
-// output, when it finds a newline it inserts the log line header
-// Note that the streambuf passed in the constructor is NOT owned by logbuf
-// --------------------------------------------------------------------------------------
-class logbuf : public std::streambuf
-{
-public:
- explicit logbuf(std::streambuf *sb);
- virtual ~logbuf();
-
- void level(unsigned level);
- unsigned level(void) const;
- // setter/getter for the level of the next line to be output
-
- void suppress(bool value);
- bool suppress(void) const;
- // suppresses the output of the line prefix
-
-protected:
- int overflow(int ch);
- // called to output the next character
-
- int sync();
- // called to sync the buffer with the actual output
-
-private:
- class logbufImpl *impl; // hides implementation to reduce dependencies
-};
-
-// --------------------------------------------------------------------------------------
-// class log_base - exists solely for the filebuf & logbuf members to be inherited, so
-// that they're available to initialize logstream's ostream base with
-// --------------------------------------------------------------------------------------
-class log_base
-{
-public:
- enum log_level // LogMask - values control what messages get logged
- {
- ll_debug = 0x0001,
- ll_info = 0x0002,
- ll_warning = 0x0004,
- ll_error = 0x0008,
- ll_trace = 0x0010,
- ll_winmsg = 0x0020,
- ll_all = 0xFFFF
- };
-
- log_base():m_buf(), m_logbuf( new logbuf(&m_buf) ) {}
- virtual ~log_base() { delete m_logbuf; }
-
- logbuf* get_logbuf(void) const { return m_logbuf; }
- // returns a pointer to the log output buffer
- // this is a concession for MSVC - trying to cast rdbuf() results in AV's, so
- // this is a less than perfect workaround
-
-protected:
- std::filebuf m_buf; // this must be declared before m_logbuf!
- logbuf *m_logbuf;
-};
-
-// --------------------------------------------------------------------------------------
-// class logstream - an output stream tailored to logging
-// --------------------------------------------------------------------------------------
-class logstream : public log_base, public std::ostream
-{
-public:
- logstream();
- ~logstream();
-
- void open(const char *filename);
-
- logstream& level(unsigned value);
- // sets the level for the next data to be output
-
- void filter(unsigned value) { m_filter = value; }
- unsigned filter(void) const { return m_filter; }
- // sets/gets the filter for the next data to be output
-
- void write_hex(const char *p_data, unsigned size, unsigned level);
-
-private:
- unsigned m_filter;
-
- void translate(const unsigned char *start, const unsigned char *end);
-};
-
-// --------------------------------------------------------------------------------------
-// class setlevel - an output manipulator for the logstream
-// --------------------------------------------------------------------------------------
-struct setlevel
-{
- setlevel(unsigned level):m_level(level) {}
- unsigned m_level;
-};
-
-// ======================================================================================
-// Function Declarations
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// operator<< - overloaded for logstream to allow filtering; doesn't work as a class
-// member so it's implemented as a standalone (manipulators like endl become ambiguous)
-// Additional overloads for custom manipulators and to resolve the odd ambiguity (e.g.
-// const char*)
-// --------------------------------------------------------------------------------------
-template <typename T>
-logstream& operator<<(logstream &lhs, const T& rhs)
-{
- std::ostream::sentry cerberus(lhs);
- if ( cerberus )
- {
- if ( lhs.get_logbuf()->level() & lhs.filter() )
- *(dynamic_cast<std::ostream*>(&lhs)) << rhs;
- }
-
- return lhs;
-}
-
-logstream& operator<<(logstream &lhs, const char *rhs);
-logstream& operator<<(logstream &lhs, const setlevel &rhs);
-
-} // namespace slug
-
-// --------------------------------------------------------------------------------------
-#endif
-// ======================================================================================
-
slic/include
diff -N streamext.h
--- streamext.h 13 Oct 2005 23:52:11 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,92 +0,0 @@
-// ======================================================================================
-// streamext.h - Version 1.1 - Copyright ©2002 Stephen W. Chappell
-// Generic stream extensions to make my life easier
-//
-// Contents:
-// - operator<< for tm, based strongly on operator<< presented in "The Standard C++
-// Locale" by Nathan C. Myers, posted at html://www.cantrip.org/locale.html
-//
-// Revision History:
-// Date | Ver | Author | Description
-// -----------+-----+--------+--------------------------------------------------------
-// 01/11/2002 | 1.1 | SwC | Problems with locale inclusion, so hdrs now always
-// | | | included; also removed from slug namespace;
-// | | | Microsoft compatibility; now outputs using specific
-// | | | format ('c' doesn't work in MSVC, time doesn't output
-// | | | readably)
-// 10/09/2001 | 1.0 | SwC | Initial Version
-// ======================================================================================
-#ifndef SLUG_STREAMEXT_H
-#define SLUG_STREAMEXT_H
-
-#include <ctime>
-#include <locale>
-#include <ostream>
-
-// ======================================================================================
-// Overloaded Operators
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// operator<< - overloading for std::tm; allows outputting of the date using standard
-// streams; Microsoft's locale implementation is a little different from the standard
-// hence the different version, also time functions aren't in the std namespace in
-// MSVC
-// --------------------------------------------------------------------------------------
-#if !defined(_MSC_VER)
- template<class charT, class traits>
- std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT,traits>& os,
- const std::tm& date)
- {
- // typedefs to make the rest of this function more readable
- typedef std::ostreambuf_iterator<charT,traits> outIter_t;
- typedef std::time_put<charT, outIter_t> Facet;
-
- // makes this safe in a multithreaded environment
- std::basic_ostream<charT, traits>::sentry cerberus(os);
- if ( cerberus )
- {
- // output the date & time in the local format
- //const Facet& fac = std::use_facet<Facet>(os.getloc());
- //fac.put(os, os, os.fill(), &date, 'c');
-
- // output the date & time, plus weekday and AM/PM indicator, in the local
- // format
- static const char format[] = "%a %x %X %p";
- const Facet& fac = std::use_facet<Facet>(os.getloc());
- if ( fac.put(os, os, os.fill(), &date, format, format + 11).failed() )
- os.setstate(os.badbit);
- }
-
- return os;
- }
-#else
- template<class charT, class traits>
- std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT,traits>& os,
- const tm& date)
- {
- // typedefs to make the rest of this function more readable
- typedef std::ostreambuf_iterator<charT,traits> outIter_t;
- typedef std::time_put<charT, outIter_t> Facet;
-
- // makes this safe in a multithreaded environment
- std::basic_ostream<charT, traits>::sentry cerberus(os);
- if ( cerberus )
- {
- // output the date & time, plus weekday and AM/PM indicator, in the local
- // format note that the simpler version of put (std version above) doesn't
- // work in MSVC
- static const char format[] = "%a %x %I:%M:%S %p";
- const Facet& fac = std::_USE(os.getloc(), Facet);
- if ( fac.put(os, os, &date, format, format + 17).failed() )
- os.setstate(os.badbit);
- }
-
- return os;
- }
-#endif
-
-// --------------------------------------------------------------------------------------
-#endif
-// ======================================================================================
-
slic/src
diff -N logstream.cc
--- logstream.cc 13 Oct 2005 23:52:11 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,419 +0,0 @@
-// ======================================================================================
-// logstream.cpp - Version 1.0 - Copyright ©2002 Stephen W. Chappell
-// A customized output stream for logging data
-//
-// Namespace: slug
-//
-// Requires: streamext.h
-//
-// Contents:
-// - logbuf - a filtering streambuf used with the logstream; it inserts the date,
-// time, and log level into the real buffer
-// - log_base - a base class for the logstream; it contains members needed to
-// initialize the other logstream base, ostream, as well as a workaround
-// for not being able to cast rdbuf() is MSVC
-// - logstream - an ostream descendent that uses the filtering logbuf to output data
-//
-// Description:
-// This customized ostream descendant extends the ostream class using standard (but
-// somewhat cryptic) methods. The logstream itself is simply an ostream descendant that
-// utilizes a custom streambuf. The custom streambuf (logbuf, a streambuf descendant)
-// is what really does the work:
-//
-// - the logbuf filters the data going to some other streambuf or streambuf descendant,
-// essentially looking for newlines so it can insert some stuff in the beginning
-// - the other streambuf does its normal thing to output data; it's supplied to the
-// logbuf constructor as a parameter
-//
-// This might seem complicated, but since the streambuf is what really does all the
-// work in standard iostreams, this makes a whole lot of sense, and, now that it's
-// done, it seems a whole lot less complicated
-//
-// For the moment, log_base contains a std::filebuf to use to actually output the data,
-// at some point it would be nice to make this a parameter so that, for example, some
-// sort of remote window logging or multithreaded logging could be implemented with
-// another custom streambuf (the logbuf itself shouldn't have to change)
-//
-// Additional credits:
-// - the basic class architecture was strongly influenced by the iostreams postings of
-// Dietmar Kühl regarding "prefix" streams at
-// http://www.inf.uni-konstanz.de/~kuehl/c++/iostream/
-//
-// Revision History:
-// Date | Ver | Author | Description
-// -----------+-----+--------+--------------------------------------------------------
-// 01/14/2002 | 1.0 | SwC | Initial Version
-// ======================================================================================
-#include <ctime>
-#include <fstream>
-#include <iomanip>
-#include <ostream>
-#include <streambuf>
-#include <string>
-#include <sstream>
-
-#include "streamext.h"
-#include "logstream.h"
-// --------------------------------------------------------------------------------------
-using std::filebuf;
-using std::endl;
-using std::setw;
-using std::ios;
-using std::ios_base;
-using std::locale;
-using std::ostream;
-using std::streambuf;
-using std::string;
-using std::stringstream;
-
-#ifndef _MSC_VER
- // MSVC doesn't include these in the std namespace
- using std::time_t;
- using std::time;
- using std::localtime;
-#endif
-
-// ======================================================================================
-
-namespace slug
-{
-
-// ======================================================================================
-// Function Implementation
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// operator<< for const char* - overloaded << operator for logstreams and const chars;
-// this is needed because the template creates ambiguities with existing ostream
-// operators
-// --------------------------------------------------------------------------------------
-logstream& operator<<(logstream &lhs, const char *rhs)
-{
- std::ostream::sentry cerberus(lhs);
- if ( cerberus )
- {
- if ( lhs.get_logbuf()->level() & lhs.filter() )
- *(dynamic_cast<std::ostream*>(&lhs)) << rhs;
- }
-
- return lhs;
-}
-
-// --------------------------------------------------------------------------------------
-// operator<< for setlevel manipulator - sets the current log level
-// --------------------------------------------------------------------------------------
-logstream& operator<<(logstream &lhs, const setlevel &rhs)
-{
- std::ostream::sentry cerberus(lhs);
- if ( cerberus )
- {
- lhs.level(rhs.m_level);
- }
-
- return lhs;
-}
-
-// ======================================================================================
-// logbufImpl Declaration
-// ======================================================================================
-
-struct logbufImpl
-{
- streambuf *m_sbuf; // the actual streambuf used to read and write chars
- bool m_bol, // remember whether we are at a new line
- m_suppress; // suppress the prefix output when set
- unsigned m_level;
- stringstream m_datebuf; // used to construct the date; this is a member so it
- // doesn't have to be imbued with the locale more than once
-
- explicit logbufImpl(streambuf *sb)
- :m_sbuf(sb),
- m_bol(true),
- m_suppress(false),
- m_level(log_base::ll_info),
- m_datebuf(ios_base::out) {}
-
- const char* leveltext(void);
-};
-
-// ======================================================================================
-// logbuf Implementation
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// logbuf::logbuf - constructor
-// --------------------------------------------------------------------------------------
-logbuf::logbuf(streambuf *sb)
- :impl( new logbufImpl(sb) )
-{
- setp(0, 0); // initializes the put buffer to be empty so overflow gets called
- impl->m_datebuf.imbue( locale("") );
-
- // I don't know if this is just a bug in the Borland compiler or what, but for some
- // reason the date that comes out in m_datebuf the first time it gets written to is
- // not correct (11/30/1990 on 1/9/2002)
- time_t now = time(0);
- impl->m_datebuf.str("");
- impl->m_datebuf << *localtime(&now);
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::~logbuf - destructor
-// --------------------------------------------------------------------------------------
-logbuf::~logbuf()
-{
- if ( !impl->m_bol )
- {
- impl->m_suppress = true;
- overflow('\n');
- }
-
- delete impl;
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::level - sets the level of the next line to be output
-// --------------------------------------------------------------------------------------
-void logbuf::level(unsigned level)
-{
- impl->m_level = level;
-
- // if the level is changed and we're not at the end of a line, then we need to
- // advance to the next line
- if ( !impl->m_bol )
- {
- overflow('\n');
- }
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::level - gets the level of the next line to be output
-// --------------------------------------------------------------------------------------
-unsigned logbuf::level(void) const
-{
- return impl->m_level;
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::suppress - suppresses the output of the line prefix
-// --------------------------------------------------------------------------------------
-void logbuf::suppress(bool value)
-{
- impl->m_suppress = value;
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::suppress - suppresses the output of the line prefix
-// --------------------------------------------------------------------------------------
-bool logbuf::suppress(void) const
-{
- return impl->m_suppress;
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::logbuf - overflow is called when the put buffer is full; since the put buffer
-// is size 0 for this logbuf, it gets called for every char; normally this is forwarded
-// to the "real" streambuf, but in the case of a newline we set m_bol, and if m_bol is
-// already set the line prefix is output
-// --------------------------------------------------------------------------------------
-int logbuf::overflow(int ch)
-{
- if ( ch != EOF )
- {
- // when we get to the beginning of a line, output the date & time, and the
- // currently set message level
- if ( impl->m_bol & !impl->m_suppress )
- {
- // get the date and save it off
- time_t now = time(0);
- impl->m_datebuf.str("");
- impl->m_datebuf << *localtime(&now) << " [" << impl->leveltext() << "] ";
- string nowstring = impl->m_datebuf.str();
-
- // output the date, etc
- if ( impl->m_sbuf->sputn(nowstring.c_str(), nowstring.size())
- != static_cast<signed>(nowstring.size()) )
- return EOF;
- else
- impl->m_bol = false;
- }
-
- int rc = impl->m_sbuf->sputc(ch);
-
- if ( ch == '\n' )
- impl->m_bol = true;
-
- return rc;
- }
-
- return 0;
-}
-
-// --------------------------------------------------------------------------------------
-// logbuf::sync - syncs the (nonexistent) buffers with the actual output
-// --------------------------------------------------------------------------------------
-int logbuf::sync()
-{
- impl->m_sbuf->pubsync();
- return 0;
-}
-
-// ======================================================================================
-// logbuf Implementation
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// logbufImpl::leveltext - outputs the best match name for the currently selected level
-// --------------------------------------------------------------------------------------
-const char* logbufImpl::leveltext(void)
-{
- if ( m_level & log_base::ll_debug ) return "DEBUG ";
- else if ( m_level & log_base::ll_info ) return "INFO ";
- else if ( m_level & log_base::ll_warning ) return "WARNING";
- else if ( m_level & log_base::ll_error ) return "ERROR ";
- else if ( m_level & log_base::ll_trace ) return "TRACE ";
- else if ( m_level & log_base::ll_winmsg ) return "WINMSG ";
-
- return "UNKNOWN";
-}
-
-// ======================================================================================
-// logstream Implementation
-// ======================================================================================
-
-// --------------------------------------------------------------------------------------
-// logstream::logstream - constructor; constructs log_base base, then uses it's m_buf
-// member to construct the ostream base; this is important - without this arrangement
-// something else would have to be done like maintaining a dynamic filebuf
-// --------------------------------------------------------------------------------------
-logstream::logstream()
- :log_base(),
- ostream( m_logbuf ),
- m_filter(log_base::ll_error | log_base::ll_warning)
-{
-}
-
-// --------------------------------------------------------------------------------------
-// logstream::~logstream - destructor
-// --------------------------------------------------------------------------------------
-logstream::~logstream()
-{
-}
-
-// --------------------------------------------------------------------------------------
-// logstream::open - open the requested file in append mode
-// --------------------------------------------------------------------------------------
-void logstream::open(const char *filename)
-{
- // open the file
- m_buf.open(filename, ios::out | ios::app);
-
- // output a divider; this is cast to ostream to avoid filtering
- bool old_suppress = get_logbuf()->suppress();
- get_logbuf()->suppress(true);
-
- setf(ios::left);
- width(115);
- char old_fill = fill('=');
- *dynamic_cast<ostream*>(this) << ">" << "<\n";
- fill(old_fill);
-
- get_logbuf()->suppress(old_suppress);
-}
-
-// --------------------------------------------------------------------------------------
-// logstream::level - sets the level for the next data to be output
-// --------------------------------------------------------------------------------------
-logstream& logstream::level(unsigned value)
-{
- get_logbuf()->level(value);
- return *this;
-}
-
-// --------------------------------------------------------------------------------------
-// logstream::write_hex - writes hex data to the log
-// --------------------------------------------------------------------------------------
-void logstream::write_hex(const char *p_data, unsigned size, unsigned level)
-{
- // if this message isn't of the right level, discard it
- if ( !(level & m_filter) ) return;
- get_logbuf()->level(level);
-
- // output message header
- *dynamic_cast<ostream*>(this) << "Hex dump (" << size << " bytes):\n\t";
-
- // output the first hex address
- char orig_fill = fill('0');
- setf(ios::right);
- *dynamic_cast<ostream*>(this) << setw(8) << std::hex << 0x00000000 << ' ';
- setf(ios::left);
- fill(orig_fill);
-
- const unsigned char *data = reinterpret_cast<const unsigned char*>(p_data),
- *line = reinterpret_cast<const unsigned char*>(p_data);
-
- // output data in rows of hex, with a break every 16 bytes, and ASCII translation at
- // the end of the line
- for ( unsigned pos = 0 ; pos < size ; ++pos, ++data )
- {
- if ( pos )
- {
- if ( !(pos % 16) ) // end of line; add the translation & go to next line
- {
- // translate the line of text
- *dynamic_cast<ostream*>(this) << " ";
- translate(line, data);
- *dynamic_cast<ostream*>(this) << "\n\t";
- line = data;
-
- // output the next line's hex address
- fill('0');
- setf(ios::right);
- *dynamic_cast<ostream*>(this) << std::hex << setw(8) << pos << ' ';
- setf(ios::left);
- fill(orig_fill);
- }
- else if ( !(pos % 8) ) // middle of line; insert an extra space
- {
- *dynamic_cast<ostream*>(this) << ' ';
- }
- }
-
- fill('0');
- *dynamic_cast<ostream*>(this) << std::hex << setw(2) << static_cast<short>(*data) << ' ';
- fill(orig_fill);
- }
-
- // we hit the end of the data in the middle somewhere, so space over to where the
- // translation should appear
- size %= 16;
- if ( size )
- {
- if ( size < 8 ) *dynamic_cast<ostream*>(this) << ' ';
- for ( unsigned i = 16 - size ; i != 0 ; --i )
- *dynamic_cast<ostream*>(this) << setw(3) << ' ';
- }
-
- // output the translation of the last (incomplete) line of data
- *dynamic_cast<ostream*>(this) << " ";
- translate(line, data);
- *dynamic_cast<ostream*>(this) << std::endl;
-}
-
-// --------------------------------------------------------------------------------------
-// logstream::translate - translates characters from start to end into ASCII text
-// --------------------------------------------------------------------------------------
-void logstream::translate(const unsigned char *start, const unsigned char *end)
-{
- for ( ; start != end ; ++start )
- {
- get_logbuf()->sputc(( *start > 32 ) ? *start : '.');
- }
-}
-
-// ======================================================================================
-
-} // namespace
-
-// ======================================================================================
-
CVSspam 0.2.8