|
basic_messenger.hhGo to the documentation of this file.00001 // 00002 // $Id: basic_messenger.hh,v 1.4 2003/11/18 11:27:31 cholm Exp $ 00003 // 00004 // ylmm::basic_messenger 00005 // Copyright (C) 2002 Christian Holm Christensen <cholm@nbi.dk> 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License 00009 // as published by the Free Software Foundation; either version 2.1 00010 // of the License, or (at your option) any later version. 00011 // 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 // Lesser General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public 00018 // License along with this library; if not, write to the Free 00019 // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 00020 // 02111-1307 USA 00021 // 00022 #ifndef YLMM_basic_messenger 00023 #define YLMM_basic_messenger 00024 #ifndef __IOSTREAM__ 00025 #include <iostream> 00026 #endif 00027 #ifndef __CSTDARG__ 00028 #include <cstdarg> 00029 #endif 00030 #ifndef __CSTDIO__ 00031 #include <cstdio> 00032 #endif 00033 00034 /** @file ylmm/basic_messenger.hh 00035 @author Christian Holm 00036 @date Sat Jan 18 03:37:32 2003 00037 @brief Base class for I/O handling */ 00038 00039 /** @defgroup common Common classes */ 00040 00041 namespace ylmm 00042 { 00043 //================================================================ 00044 /** @class basic_lock basic_messenger.hh <ylmm/basic_messenger.hh> 00045 @brief Single threaded locking object. 00046 00047 Used by ylmm::basic_messenger to insure thread safe static 00048 creation of the default output handler. This implementation does 00049 nothing. In a real multi-threaded application, the user should 00050 pass a proper mutex locking class, defining at a minimum the 00051 lock and unlock member functions. 00052 @see @ref thread_issues 00053 @ingroup common 00054 */ 00055 class basic_lock 00056 { 00057 public: 00058 /** Aquire this lock. This implemtation does nothing. */ 00059 void lock() {} 00060 /** Release this lock. This implemtation does nothing. */ 00061 void unlock() {} 00062 }; 00063 00064 //================================================================ 00065 /** @class basic_messenger basic_messenger.hh <ylmm/basic_messenger.hh> 00066 @brief Base class for output handling. 00067 @see @ref messenger_doc 00068 @param lock The type of thread syncronisation locks used in the 00069 application. Per default a single threaded locking mechanism 00070 (that is - no locks) is used. The application should pass the 00071 appropiate type here to make the use of this class thread safe. 00072 @ingroup common 00073 */ 00074 template <typename Lock=basic_lock> 00075 class basic_messenger 00076 { 00077 private: 00078 static basic_messenger* _default_handler; /** The default handler 00079 */ 00080 static Lock _lock; /** Lock used to insure safe thread 00081 creation of the default handler */ 00082 protected: 00083 std::ostream* _err_stream; /** The stream to write errors to */ 00084 std::ostream* _msg_stream; /** The stream to write messages to */ 00085 /// 00086 /** The real print method 00087 @param o Output stream 00088 @param format @c printf like format string 00089 @param ap variadic arugment list */ 00090 void print(std::ostream* o, const char* format, va_list ap); 00091 public: 00092 /** Constructor. */ 00093 basic_messenger(std::ostream& msg=std::cout, 00094 std::ostream& err=std::cerr); 00095 /** Destructor. */ 00096 virtual ~basic_messenger() {} 00097 00098 //@{ 00099 /// @name Handling streams 00100 /** Set stream to write errors to. 00101 @param err_str The stream to write to 00102 @return @a err_str */ 00103 std::ostream& error_stream(std::ostream& err_str); 00104 /** Get the error stream 00105 @return the error stream */ 00106 std::ostream& error_stream() { return *_err_stream; } 00107 /** Set stream to write messages to. 00108 @param msg_str The stream to write to 00109 @return @a msg_str */ 00110 std::ostream& message_stream(std::ostream& msg_str); 00111 /** Get the messages stream 00112 @return the messages stream */ 00113 std::ostream& message_stream() { return *_msg_stream; } 00114 //@} 00115 00116 //@{ 00117 /// @name Normal messages 00118 /** Print a message on the message stream. 00119 @param format The @c printf like format string */ 00120 virtual void message(const char* format, ...); 00121 /** Print a message on the message stream. 00122 @param format The @c printf like format string 00123 @param ap The variadic arguments. */ 00124 virtual void message(const char* format, va_list ap); 00125 //@} 00126 00127 //@{ 00128 /// @name Error messages 00129 /** Print a error on the error stream. 00130 @param format The @c printf like format string */ 00131 virtual void error(const char* format, ...); 00132 /** Print a error on the error stream. 00133 @param format The @c printf like format string 00134 @param ap The variadic arguments. */ 00135 virtual void error(const char* format, va_list ap); 00136 //@} 00137 00138 /** Get the default handler. 00139 @return the default handler. */ 00140 static basic_messenger* default_handler(); 00141 }; 00142 //__________________________________________________________________ 00143 template<typename L> 00144 inline 00145 basic_messenger<L>::basic_messenger(std::ostream& msg_str, 00146 std::ostream& err_str) 00147 { 00148 _msg_stream = 0; 00149 _err_stream = 0; 00150 message_stream(msg_str); 00151 error_stream(err_str); 00152 } 00153 //__________________________________________________________________ 00154 template<typename L> 00155 inline std::ostream& 00156 basic_messenger<L>::error_stream(std::ostream& s) 00157 { 00158 _err_stream = &s; 00159 return *_err_stream; 00160 } 00161 //__________________________________________________________________ 00162 template<typename L> 00163 inline std::ostream& 00164 basic_messenger<L>::message_stream(std::ostream& s) 00165 { 00166 _msg_stream = &s; 00167 return *_msg_stream; 00168 } 00169 //__________________________________________________________________ 00170 template<typename L> 00171 inline void 00172 basic_messenger<L>::print(std::ostream* o, const char* f, va_list ap) 00173 { 00174 static char buf[1024]; 00175 if (!o || o->bad()) return; 00176 #ifdef HAVE_VSNPRINTF 00177 vsnprintf(buf, 1024, f, ap); 00178 #else 00179 vsprintf(buf, f, ap); 00180 #endif 00181 *o << buf << std::flush; 00182 } 00183 //__________________________________________________________________ 00184 template<typename L> 00185 inline void 00186 basic_messenger<L>::message(const char* msg, ...) 00187 { 00188 va_list ap; 00189 va_start(ap, msg); 00190 message(msg, ap); 00191 va_end(ap); 00192 } 00193 //__________________________________________________________________ 00194 template<typename L> 00195 inline void 00196 basic_messenger<L>::message(const char* msg, va_list ap) 00197 { 00198 print(_msg_stream, msg, ap); 00199 } 00200 //__________________________________________________________________ 00201 template<typename L> 00202 inline void 00203 basic_messenger<L>::error(const char* err, ...) 00204 { 00205 va_list ap; 00206 va_start(ap, err); 00207 error(err, ap); 00208 va_end(ap); 00209 } 00210 //__________________________________________________________________ 00211 template<typename L> 00212 inline void 00213 basic_messenger<L>::error(const char* err, va_list ap) 00214 { 00215 print(_err_stream, err, ap); 00216 } 00217 //__________________________________________________________________ 00218 template<typename L> 00219 inline basic_messenger<L>* 00220 basic_messenger<L>::default_handler() 00221 { 00222 // Double checking locking idom to avoid race conditions. 00223 if (!_default_handler) { 00224 _lock.lock(); 00225 if (!_default_handler) 00226 _default_handler = new basic_messenger(std::cout,std::cerr); 00227 _lock.unlock(); 00228 } 00229 return _default_handler; 00230 } 00231 //__________________________________________________________________ 00232 template<typename L> basic_messenger<L>* 00233 basic_messenger<L>::_default_handler = 0; 00234 //__________________________________________________________________ 00235 template<typename L> L basic_messenger<L>::_lock; 00236 } 00237 00238 #endif 00239 //____________________________________________________________________ 00240 // 00241 // EOF 00242 // Christian Holm (home page) Last update Fri Jul 8 12:58:03 2005 Created by DoxyGen 1.4.3-20050530 |