/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */ /* $Id: cmnMultiplexerStreambufProxy.h,v 1.14 2007/04/26 19:33:57 anton Exp $ Author(s): Ofri Sadowsky Created on: 2002-05-20 (C) Copyright 2002-2007 Johns Hopkins University (JHU), All Rights Reserved. --- begin cisst license - do not edit --- This software is provided "as is" under an open source license, with no warranty. The complete license can be found in license.txt and http://www.cisst.org/cisst/license.txt. --- end cisst license --- */ /*! \file \brief Description of types for dynamic control of output messages. */ #ifndef _cmnMultiplexerStreambufProxy_h #define _cmnMultiplexerStreambufProxy_h #include #include #include #include /*! \brief Types for dynamic control of output messages. This includes debugging information, error reporting, state logging etc. This file declares *class cmnMultiplexerStreambufProxy*. It is a templated class derived from the standard library's basic_streambuf. But is stores a Level Of Detail (LOD) descriptor that applies to each message that's output through it. The LOD descriptor is transferred to a cmnLODMultiplexerStreambuf object, that stores a list of LODed output channels, and decides which ones will be actually used. The proxy is implemented by overriding basic_streambuf output functions xsputn(), overflow() and sync(). Usage: Include the module in your application with: \#include Attach a cmnMultiplexerStreambufProxy object with an ostream. The output functions << , put(), write() etc will operate directly on the cmnMultiplexerStreambufProxy. Example of using a cmnLODOutputMultiplexer, which is an ostream that is attached to a proxy. Assume that the object lodMultiplexerStreambuf is a cmnLODMultiplexerStreambuf. \code // The multiple output channels ofstream log("logfile.txt"); windowoutputstream display; // hypothesized class lodMultiplexerStreambuf.AddChannel(log.rdbuf(), 5); lodMultiplexerStreambuf.AddChannel(windowoutputstream.rdbuf(), 2); cmnLODMultiplexer multiplexerOutput(&lodMultiplexetStreambuf, 3); multiplexerStreambuf << "Hello, world" << endl; // channel the message only to 'log' \endcode Notes: -# It is assumed that none of the output channels modifies the data arguments. -# cmnMultiplexerStreambufProxy does not buffer data. Instead, whenever at attempt is made to use stream::put() on a stream with a multiplexer streambuf, the cmnMultiplexerStreambuf::overflow() is called automatically, and it forwards the character to the output channels. \sa C++ manual on basic_ostream and basic_streambuf. cmnOutputMultiplexer.h and cmnLODMultiplexerStreambuf.h */ template class cmnMultiplexerStreambufProxy : public std::basic_streambuf<_element, _trait> { public: typedef cmnLODMultiplexerStreambuf<_element, _trait> ChannelType; typedef typename ChannelType::LodType LodType; typedef typename std::basic_streambuf<_element, _trait>::int_type int_type; /*! Constructor: initialize the true output multiplexer and the current LOD. */ cmnMultiplexerStreambufProxy(ChannelType *output, LodType lod) : m_OutputChannel(output), m_LOD(lod) {} /*! Copy Ctor is unnecessary, but I wrote it anyway. */ cmnMultiplexerStreambufProxy(const cmnMultiplexerStreambufProxy<_element, _trait> & other) :/* basic_streambuf<_element, _trait>( (basic_streambuf<_element, _trait> &)other),*/ m_OutputChannel(other.GetOutput()), m_LOD(other.GetLOD()) {} /*! Returns the Level of Detail. */ LodType GetLOD(void) const { return m_LOD; } /*! Sets the Level of Detail. */ void SetLOD(LodType lod) { m_LOD = lod; } /*! Returns a pointer to the output multiplexer. */ ChannelType * GetOutput(void) const { return m_OutputChannel; } // Here we override the basic_streambuf methods for multiplexing. // This part is declared 'protected' following the declarations of // basic_streambuf. See basic_streambuf documentation for more // details. protected: /*! Override the basic_streambuf xsputn to do the multiplexing. */ virtual std::streamsize xsputn(const _element *s, std::streamsize n); /*! Override the basic_streambuf sync for multiplexing. */ virtual int sync(void); /*! Override the basic_streambuf overflow for multiplexing. overflow() is called when sputc() discovers it does not have space in the storage buffer. In our case, it's always. See more on it in the basic_streambuf documentation. */ virtual int_type overflow(int_type c = _trait::eof()); private: ChannelType * m_OutputChannel; LodType m_LOD; }; //******************************** // Template method implementation //******************************** /*! Override the basic_streambuf xsputn to do the multiplexing. */ template std::streamsize cmnMultiplexerStreambufProxy<_element, _trait>::xsputn(const _element *s, std::streamsize n) { return m_OutputChannel->xsputn(s, n, m_LOD); } /*! Override the basic_streambuf sync for multiplexing. */ template int cmnMultiplexerStreambufProxy<_element, _trait>::sync() { return m_OutputChannel->sync(); } /*! Override the basic_streambuf overflow for multiplexing. overflow() is called when * sputc() discovers it does not have space in the storage buffer. In our case, * it's always. See more on it in the basic_streambuf documentation. */ template typename cmnMultiplexerStreambufProxy<_element, _trait>::int_type cmnMultiplexerStreambufProxy<_element, _trait>::overflow(int_type c) { return m_OutputChannel->overflow(c, m_LOD); } #endif // _cmnMultiplexerStreambufProxy_h // **************************************************************************** // Change History // **************************************************************************** // // $Log: cmnMultiplexerStreambufProxy.h,v $ // Revision 1.14 2007/04/26 19:33:57 anton // All files in libraries: Applied new license text, separate copyright and // updated dates, added standard header where missing. // // Revision 1.13 2006/11/20 20:33:19 anton // Licensing: Applied new license to cisstCommon, cisstVector, cisstNumerical, // cisstInteractive, cisstImage and cisstOSAbstraction. // // Revision 1.12 2006/10/06 14:29:33 anton // All libraries: Re-ordered #include to include cmnPortability.h before any // other file, including system header files. // // Revision 1.11 2006/01/03 03:33:04 anton // cisstCommon Doxygen: Use \code \endcode instead of
, updated
// cmnTypeTraits to avoid all specialization to appear, updated CISST_DEPRECATED.
//
// Revision 1.10  2005/10/06 16:56:37  anton
// Doxygen: Corrected errors and some warnings detected by Doxygen 1.4.3.
//
// Revision 1.9  2005/09/26 15:41:46  anton
// cisst: Added modelines for emacs and vi.
//
// Revision 1.8  2005/05/19 19:29:00  anton
// cisst libs: Added the license to cisstCommon and cisstVector
//
// Revision 1.7  2004/10/25 13:52:05  anton
// Doxygen documentation:  Cleanup all the useless \ingroup.
//
// Revision 1.6  2004/10/09 18:52:16  ofri
// Some cleanup in cisstCommon header files.  gcc on cygwin prints a bunch of
// warnings when it encounters #pragma warning .  Some files had that prama used
// if WIN32 is defined, which is the case with cygwin/gcc.  I substituted that with
// including cmnPortability and adding the warning disable that.
//
// Revision 1.5  2003/09/17 17:04:52  anton
// changed template parameters to _aBetterName
//
// Revision 1.4  2003/09/17 14:18:46  anton
// removed useless cmnEXPORT in front of templated classes
//
// Revision 1.3  2003/09/09 18:53:46  anton
// changed from double quotes to <> for all #include
//
// Revision 1.2  2003/06/23 18:48:57  anton
// remove tabs
//
// Revision 1.1.1.1  2003/05/30 19:47:59  anton
// no message
//
//
// ****************************************************************************