log4cplus  1.1.0
deviceappender.hxx
Go to the documentation of this file.
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