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 <boost/log/detail/config.hpp>
17#include <vector>
18#include <algorithm>
19#include <boost/log/detail/parameter_tools.hpp>
20#include <boost/log/sinks/auto_newline_mode.hpp>
21#include <boost/log/sinks/text_ostream_backend.hpp>
22#include <boost/log/detail/header.hpp>
23
24namespace boost {
25
26BOOST_LOG_OPEN_NAMESPACE
27
28namespace sinks {
29
30//! Sink implementation
31template< typename CharT >
32struct basic_text_ostream_backend< CharT >::implementation
33{
34 //! Type of the container that holds all aggregated streams
35 typedef std::vector< shared_ptr< stream_type > > ostream_sequence;
36
37 //! Output stream list
38 ostream_sequence m_Streams;
39 //! Indicates whether to append a trailing newline after every log record
40 auto_newline_mode m_AutoNewlineMode;
41 //! Auto-flush flag
42 bool m_fAutoFlush;
43
44 implementation(auto_newline_mode auto_newline, bool auto_flush) :
45 m_AutoNewlineMode(auto_newline),
46 m_fAutoFlush(auto_flush)
47 {
48 }
49};
50
51
52//! Constructor
53template< typename CharT >
54BOOST_LOG_API basic_text_ostream_backend< CharT >::basic_text_ostream_backend()
55{
56 construct(log::aux::empty_arg_list());
57}
58
59//! Constructor implementation
60template< typename CharT >
61BOOST_LOG_API void basic_text_ostream_backend< CharT >::construct(auto_newline_mode auto_newline, bool auto_flush)
62{
63 m_pImpl = new implementation(auto_newline, auto_flush);
64}
65
66//! Destructor (just to make it link from the shared library)
67template< typename CharT >
68BOOST_LOG_API basic_text_ostream_backend< CharT >::~basic_text_ostream_backend()
69{
70 delete m_pImpl;
71}
72
73//! Selects whether a trailing newline should be automatically inserted after every log record.
74template< typename CharT >
75BOOST_LOG_API void basic_text_ostream_backend< CharT >::set_auto_newline_mode(auto_newline_mode mode)
76{
77 m_pImpl->m_AutoNewlineMode = mode;
78}
79
80//! The method adds a new stream to the sink
81template< typename CharT >
82BOOST_LOG_API void basic_text_ostream_backend< CharT >::add_stream(shared_ptr< stream_type > const& strm)
83{
84 typename implementation::ostream_sequence::iterator it =
85 std::find(m_pImpl->m_Streams.begin(), m_pImpl->m_Streams.end(), strm);
86 if (it == m_pImpl->m_Streams.end())
87 {
88 m_pImpl->m_Streams.push_back(strm);
89 }
90}
91
92//! The method removes a stream from the sink
93template< typename CharT >
94BOOST_LOG_API void basic_text_ostream_backend< CharT >::remove_stream(shared_ptr< stream_type > const& strm)
95{
96 typename implementation::ostream_sequence::iterator it =
97 std::find(m_pImpl->m_Streams.begin(), m_pImpl->m_Streams.end(), strm);
98 if (it != m_pImpl->m_Streams.end())
99 m_pImpl->m_Streams.erase(it);
100}
101
102//! Sets the flag to automatically flush buffers after each logged line
103template< typename CharT >
104BOOST_LOG_API void basic_text_ostream_backend< CharT >::auto_flush(bool f)
105{
106 m_pImpl->m_fAutoFlush = f;
107}
108
109//! The method writes the message to the sink
110template< typename CharT >
111BOOST_LOG_API void basic_text_ostream_backend< CharT >::consume(record_view const&, string_type const& message)
112{
113 typename string_type::const_pointer const p = message.data();
114 typename string_type::size_type const s = message.size();
115 typename implementation::ostream_sequence::const_iterator
116 it = m_pImpl->m_Streams.begin(), end = m_pImpl->m_Streams.end();
117 bool need_trailing_newline = false;
118 if (m_pImpl->m_AutoNewlineMode != disabled_auto_newline)
119 need_trailing_newline = (m_pImpl->m_AutoNewlineMode == always_insert || s == 0u || p[s - 1u] != static_cast< char_type >('\n'));
120
121 for (; it != end; ++it)
122 {
123 stream_type* const strm = it->get();
124 if (BOOST_LIKELY(strm->good()))
125 {
126 strm->write(p, static_cast< std::streamsize >(s));
127 if (need_trailing_newline)
128 strm->put(static_cast< char_type >('\n'));
129
130 if (m_pImpl->m_fAutoFlush)
131 strm->flush();
132 }
133 }
134}
135
136//! The method flushes the associated streams
137template< typename CharT >
138BOOST_LOG_API void basic_text_ostream_backend< CharT >::flush()
139{
140 typename implementation::ostream_sequence::const_iterator
141 it = m_pImpl->m_Streams.begin(), end = m_pImpl->m_Streams.end();
142 for (; it != end; ++it)
143 {
144 stream_type* const strm = it->get();
145 if (BOOST_LIKELY(strm->good()))
146 strm->flush();
147 }
148}
149
150//! Explicitly instantiate sink backend implementation
151#ifdef BOOST_LOG_USE_CHAR
152template class basic_text_ostream_backend< char >;
153#endif
154#ifdef BOOST_LOG_USE_WCHAR_T
155template class basic_text_ostream_backend< wchar_t >;
156#endif
157
158} // namespace sinks
159
160BOOST_LOG_CLOSE_NAMESPACE // namespace log
161
162} // namespace boost
163
164#include <boost/log/detail/footer.hpp>
165

source code of boost/libs/log/src/text_ostream_backend.cpp