1 /*
2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7 /*!
8 * \file text_ostream_backend.cpp
9 * \author Andrey Semashev
10 * \date 19.04.2007
11 *
12 * \brief This header is the Boost.Log library implementation, see the library documentation
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14 */
15
16 #include <vector>
17 #include <algorithm>
18 #include <boost/log/sinks/text_ostream_backend.hpp>
19 #include <boost/log/detail/header.hpp>
20
21 namespace boost {
22
23 BOOST_LOG_OPEN_NAMESPACE
24
25 namespace sinks {
26
27 //! Sink implementation
28 template< typename CharT >
29 struct basic_text_ostream_backend< CharT >::implementation
30 {
31 //! Type of the container that holds all aggregated streams
32 typedef std::vector< shared_ptr< stream_type > > ostream_sequence;
33
34 //! Output stream list
35 ostream_sequence m_Streams;
36 //! Auto-flush flag
37 bool m_fAutoFlush;
38
implementationboost::sinks::basic_text_ostream_backend::implementation39 implementation() : m_fAutoFlush(false)
40 {
41 }
42 };
43
44
45 //! Constructor
46 template< typename CharT >
basic_text_ostream_backend()47 BOOST_LOG_API basic_text_ostream_backend< CharT >::basic_text_ostream_backend() : m_pImpl(new implementation())
48 {
49 }
50
51 //! Destructor (just to make it link from the shared library)
52 template< typename CharT >
~basic_text_ostream_backend()53 BOOST_LOG_API basic_text_ostream_backend< CharT >::~basic_text_ostream_backend()
54 {
55 delete m_pImpl;
56 }
57
58 //! The method adds a new stream to the sink
59 template< typename CharT >
add_stream(shared_ptr<stream_type> const & strm)60 BOOST_LOG_API void basic_text_ostream_backend< CharT >::add_stream(shared_ptr< stream_type > const& strm)
61 {
62 typename implementation::ostream_sequence::iterator it =
63 std::find(m_pImpl->m_Streams.begin(), m_pImpl->m_Streams.end(), strm);
64 if (it == m_pImpl->m_Streams.end())
65 {
66 m_pImpl->m_Streams.push_back(strm);
67 }
68 }
69
70 //! The method removes a stream from the sink
71 template< typename CharT >
remove_stream(shared_ptr<stream_type> const & strm)72 BOOST_LOG_API void basic_text_ostream_backend< CharT >::remove_stream(shared_ptr< stream_type > const& strm)
73 {
74 typename implementation::ostream_sequence::iterator it =
75 std::find(m_pImpl->m_Streams.begin(), m_pImpl->m_Streams.end(), strm);
76 if (it != m_pImpl->m_Streams.end())
77 m_pImpl->m_Streams.erase(it);
78 }
79
80 //! Sets the flag to automatically flush buffers after each logged line
81 template< typename CharT >
auto_flush(bool f)82 BOOST_LOG_API void basic_text_ostream_backend< CharT >::auto_flush(bool f)
83 {
84 m_pImpl->m_fAutoFlush = f;
85 }
86
87 //! The method writes the message to the sink
88 template< typename CharT >
consume(record_view const &,string_type const & message)89 BOOST_LOG_API void basic_text_ostream_backend< CharT >::consume(record_view const&, string_type const& message)
90 {
91 typename string_type::const_pointer const p = message.data();
92 typename string_type::size_type const s = message.size();
93 typename implementation::ostream_sequence::const_iterator
94 it = m_pImpl->m_Streams.begin(), end = m_pImpl->m_Streams.end();
95 for (; it != end; ++it)
96 {
97 stream_type* const strm = it->get();
98 if (strm->good())
99 {
100 strm->write(p, static_cast< std::streamsize >(s));
101 strm->put(static_cast< char_type >('\n'));
102
103 if (m_pImpl->m_fAutoFlush)
104 strm->flush();
105 }
106 }
107 }
108
109 //! The method flushes the associated streams
110 template< typename CharT >
flush()111 BOOST_LOG_API void basic_text_ostream_backend< CharT >::flush()
112 {
113 typename implementation::ostream_sequence::const_iterator
114 it = m_pImpl->m_Streams.begin(), end = m_pImpl->m_Streams.end();
115 for (; it != end; ++it)
116 {
117 stream_type* const strm = it->get();
118 if (strm->good())
119 strm->flush();
120 }
121 }
122
123 //! Explicitly instantiate sink backend implementation
124 #ifdef BOOST_LOG_USE_CHAR
125 template class basic_text_ostream_backend< char >;
126 #endif
127 #ifdef BOOST_LOG_USE_WCHAR_T
128 template class basic_text_ostream_backend< wchar_t >;
129 #endif
130
131 } // namespace sinks
132
133 BOOST_LOG_CLOSE_NAMESPACE // namespace log
134
135 } // namespace boost
136
137 #include <boost/log/detail/footer.hpp>
138