log4cplus
1.1.0
|
00001 // Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved. 00002 // 00003 // Redistribution and use in source and binary forms, with or without modifica- 00004 // tion, are permitted provided that the following conditions are met: 00005 // 00006 // 1. Redistributions of source code must retain the above copyright notice, 00007 // this list of conditions and the following disclaimer. 00008 // 00009 // 2. Redistributions in binary form must reproduce the above copyright notice, 00010 // this list of conditions and the following disclaimer in the documentation 00011 // and/or other materials provided with the distribution. 00012 // 00013 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00014 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00015 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00016 // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00017 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 00018 // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00019 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00020 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00021 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00022 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00023 00024 #ifndef LOG4CPLUS_BOOST_DEVICEAPPENDER_HXX 00025 #define LOG4CPLUS_BOOST_DEVICEAPPENDER_HXX 00026 00027 #include <log4cplus/config.hxx> 00028 00029 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00030 #pragma once 00031 #endif 00032 00033 #include <boost/utility/enable_if.hpp> 00034 #include <boost/type_traits/is_same.hpp> 00035 #include <boost/mpl/not.hpp> 00036 #include <boost/iostreams/operations.hpp> 00037 #include <boost/shared_ptr.hpp> 00038 #include <log4cplus/appender.h> 00039 00040 00041 namespace log4cplus 00042 { 00043 00044 00045 namespace device_appender_detail 00046 { 00047 00048 00049 template <typename T> 00050 struct device_type_traits 00051 { 00052 typedef T & device_type; 00053 00054 static 00055 device_type 00056 unwrap (device_type x) 00057 { 00058 return x; 00059 } 00060 }; 00061 00062 00063 template <typename T> 00064 struct device_type_traits<boost::shared_ptr<T> > 00065 { 00066 typedef boost::shared_ptr<T> device_type; 00067 00068 static 00069 T & 00070 unwrap (device_type const & ptr) 00071 { 00072 return *ptr; 00073 } 00074 }; 00075 00076 00077 } // namespace device_appender_detail 00078 00079 00080 template <typename Device> 00081 class DeviceAppender 00082 : public Appender 00083 { 00084 public: 00085 typedef device_appender_detail::device_type_traits<Device> device_traits; 00086 typedef typename device_traits::device_type device_type; 00087 00088 template <typename D> 00089 DeviceAppender (D & d, bool close_device = true) 00090 : device (d) 00091 , close_flag (close_device) 00092 { } 00093 00094 template <typename D> 00095 DeviceAppender (boost::shared_ptr<D> const & d, bool close_device = true) 00096 : device (d) 00097 , close_flag (close_device) 00098 { } 00099 00100 template <typename D> 00101 DeviceAppender (D & d, const helpers::Properties & props) 00102 : Appender (props) 00103 , device (d) 00104 { 00105 if (props.exists (LOG4CPLUS_TEXT ("CloseDevice"))) 00106 close_flag = true; 00107 else 00108 close_flag = false; 00109 } 00110 00111 template <typename D> 00112 DeviceAppender (boost::shared_ptr<D> const & d, 00113 const helpers::Properties & props) 00114 : Appender (props) 00115 , device (d) 00116 { 00117 if (props.exists (LOG4CPLUS_TEXT ("CloseDevice"))) 00118 close_flag = true; 00119 else 00120 close_flag = false; 00121 } 00122 00123 virtual 00124 ~DeviceAppender () 00125 { } 00126 00127 virtual 00128 void 00129 close () 00130 { 00131 if (close_flag) 00132 boost::iostreams::close (device_traits::unwrap (device)); 00133 } 00134 00135 protected: 00136 virtual 00137 void 00138 append (log4cplus::spi::InternalLoggingEvent const & event) 00139 { 00140 tstring & str = formatEvent (event); 00141 boost::iostreams::write (device_traits::unwrap (device), 00142 str.c_str (), str.size ()); 00143 } 00144 00145 device_type device; 00146 bool close_flag; 00147 00148 private: 00149 DeviceAppender (DeviceAppender const &); 00150 DeviceAppender & operator = (DeviceAppender const &); 00151 }; 00152 00153 00154 template <typename T> 00155 inline 00156 SharedAppenderPtr 00157 make_device_appender (T & d, bool close_device = true) 00158 { 00159 SharedAppenderPtr app (new DeviceAppender<T> (d, close_device)); 00160 return app; 00161 } 00162 00163 00164 template <typename T> 00165 inline 00166 SharedAppenderPtr 00167 make_device_appender (T & d, const helpers::Properties & props) 00168 { 00169 SharedAppenderPtr app (new DeviceAppender<T> (d, props)); 00170 return app; 00171 } 00172 00173 00174 template <typename T> 00175 inline 00176 SharedAppenderPtr 00177 make_device_appender_sp (boost::shared_ptr<T> const & p, 00178 bool close_device = true) 00179 { 00180 SharedAppenderPtr app ( 00181 new DeviceAppender<boost::shared_ptr<T> > (p, close_device)); 00182 return app; 00183 } 00184 00185 00186 template <typename T> 00187 inline 00188 SharedAppenderPtr 00189 make_device_appender_sp (boost::shared_ptr<T> const & p, 00190 const helpers::Properties & props) 00191 { 00192 SharedAppenderPtr app ( 00193 new DeviceAppender<boost::shared_ptr<T> > (p, props)); 00194 return app; 00195 } 00196 00197 00198 } // namespace log4cplus 00199 00200 00201 #endif // LOG4CPLUS_BOOST_DEVICEAPPENDER_HXX