You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
4.9 KiB

  1. // Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved.
  2. //
  3. // Redistribution and use in source and binary forms, with or without modifica-
  4. // tion, are permitted provided that the following conditions are met:
  5. //
  6. // 1. Redistributions of source code must retain the above copyright notice,
  7. // this list of conditions and the following disclaimer.
  8. //
  9. // 2. Redistributions in binary form must reproduce the above copyright notice,
  10. // this list of conditions and the following disclaimer in the documentation
  11. // and/or other materials provided with the distribution.
  12. //
  13. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  14. // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  15. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16. // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  17. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  18. // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  19. // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  22. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. #ifndef LOG4CPLUS_BOOST_DEVICEAPPENDER_HXX
  24. #define LOG4CPLUS_BOOST_DEVICEAPPENDER_HXX
  25. #include <log4cplus/config.hxx>
  26. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  27. #pragma once
  28. #endif
  29. #include <boost/utility/enable_if.hpp>
  30. #include <boost/type_traits/is_same.hpp>
  31. #include <boost/mpl/not.hpp>
  32. #include <boost/iostreams/operations.hpp>
  33. #include <boost/shared_ptr.hpp>
  34. #include <log4cplus/appender.h>
  35. namespace log4cplus
  36. {
  37. namespace device_appender_detail
  38. {
  39. template <typename T>
  40. struct device_type_traits
  41. {
  42. typedef T & device_type;
  43. static
  44. device_type
  45. unwrap (device_type x)
  46. {
  47. return x;
  48. }
  49. };
  50. template <typename T>
  51. struct device_type_traits<boost::shared_ptr<T> >
  52. {
  53. typedef boost::shared_ptr<T> device_type;
  54. static
  55. T &
  56. unwrap (device_type const & ptr)
  57. {
  58. return *ptr;
  59. }
  60. };
  61. } // namespace device_appender_detail
  62. template <typename Device>
  63. class DeviceAppender
  64. : public Appender
  65. {
  66. public:
  67. typedef device_appender_detail::device_type_traits<Device> device_traits;
  68. typedef typename device_traits::device_type device_type;
  69. template <typename D>
  70. DeviceAppender (D & d, bool close_device = true)
  71. : device (d)
  72. , close_flag (close_device)
  73. { }
  74. template <typename D>
  75. DeviceAppender (boost::shared_ptr<D> const & d, bool close_device = true)
  76. : device (d)
  77. , close_flag (close_device)
  78. { }
  79. template <typename D>
  80. DeviceAppender (D & d, const helpers::Properties & props)
  81. : Appender (props)
  82. , device (d)
  83. {
  84. if (props.exists (LOG4CPLUS_TEXT ("CloseDevice")))
  85. close_flag = true;
  86. else
  87. close_flag = false;
  88. }
  89. template <typename D>
  90. DeviceAppender (boost::shared_ptr<D> const & d,
  91. const helpers::Properties & props)
  92. : Appender (props)
  93. , device (d)
  94. {
  95. if (props.exists (LOG4CPLUS_TEXT ("CloseDevice")))
  96. close_flag = true;
  97. else
  98. close_flag = false;
  99. }
  100. virtual
  101. ~DeviceAppender ()
  102. { }
  103. virtual
  104. void
  105. close ()
  106. {
  107. if (close_flag)
  108. boost::iostreams::close (device_traits::unwrap (device));
  109. }
  110. protected:
  111. virtual
  112. void
  113. append (log4cplus::spi::InternalLoggingEvent const & event)
  114. {
  115. tstring & str = formatEvent (event);
  116. boost::iostreams::write (device_traits::unwrap (device),
  117. str.c_str (), str.size ());
  118. }
  119. device_type device;
  120. bool close_flag;
  121. private:
  122. DeviceAppender (DeviceAppender const &);
  123. DeviceAppender & operator = (DeviceAppender const &);
  124. };
  125. template <typename T>
  126. inline
  127. SharedAppenderPtr
  128. make_device_appender (T & d, bool close_device = true)
  129. {
  130. SharedAppenderPtr app (new DeviceAppender<T> (d, close_device));
  131. return app;
  132. }
  133. template <typename T>
  134. inline
  135. SharedAppenderPtr
  136. make_device_appender (T & d, const helpers::Properties & props)
  137. {
  138. SharedAppenderPtr app (new DeviceAppender<T> (d, props));
  139. return app;
  140. }
  141. template <typename T>
  142. inline
  143. SharedAppenderPtr
  144. make_device_appender_sp (boost::shared_ptr<T> const & p,
  145. bool close_device = true)
  146. {
  147. SharedAppenderPtr app (
  148. new DeviceAppender<boost::shared_ptr<T> > (p, close_device));
  149. return app;
  150. }
  151. template <typename T>
  152. inline
  153. SharedAppenderPtr
  154. make_device_appender_sp (boost::shared_ptr<T> const & p,
  155. const helpers::Properties & props)
  156. {
  157. SharedAppenderPtr app (
  158. new DeviceAppender<boost::shared_ptr<T> > (p, props));
  159. return app;
  160. }
  161. } // namespace log4cplus
  162. #endif // LOG4CPLUS_BOOST_DEVICEAPPENDER_HXX