summaryrefslogtreecommitdiff
path: root/libs/log/src/text_ostream_backend.cpp
blob: f55df12a968d52410e5fe916daf0b01ac70d9ef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 *          Copyright Andrey Semashev 2007 - 2014.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   text_ostream_backend.cpp
 * \author Andrey Semashev
 * \date   19.04.2007
 *
 * \brief  This header is the Boost.Log library implementation, see the library documentation
 *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
 */

#include <vector>
#include <algorithm>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/detail/header.hpp>

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace sinks {

//! Sink implementation
template< typename CharT >
struct basic_text_ostream_backend< CharT >::implementation
{
    //! Type of the container that holds all aggregated streams
    typedef std::vector< shared_ptr< stream_type > > ostream_sequence;

    //! Output stream list
    ostream_sequence m_Streams;
    //! Auto-flush flag
    bool m_fAutoFlush;

    implementation() : m_fAutoFlush(false)
    {
    }
};


//! Constructor
template< typename CharT >
BOOST_LOG_API basic_text_ostream_backend< CharT >::basic_text_ostream_backend() : m_pImpl(new implementation())
{
}

//! Destructor (just to make it link from the shared library)
template< typename CharT >
BOOST_LOG_API basic_text_ostream_backend< CharT >::~basic_text_ostream_backend()
{
    delete m_pImpl;
}

//! The method adds a new stream to the sink
template< typename CharT >
BOOST_LOG_API void basic_text_ostream_backend< CharT >::add_stream(shared_ptr< stream_type > const& strm)
{
    typename implementation::ostream_sequence::iterator it =
        std::find(m_pImpl->m_Streams.begin(), m_pImpl->m_Streams.end(), strm);
    if (it == m_pImpl->m_Streams.end())
    {
        m_pImpl->m_Streams.push_back(strm);
    }
}

//! The method removes a stream from the sink
template< typename CharT >
BOOST_LOG_API void basic_text_ostream_backend< CharT >::remove_stream(shared_ptr< stream_type > const& strm)
{
    typename implementation::ostream_sequence::iterator it =
        std::find(m_pImpl->m_Streams.begin(), m_pImpl->m_Streams.end(), strm);
    if (it != m_pImpl->m_Streams.end())
        m_pImpl->m_Streams.erase(it);
}

//! Sets the flag to automatically flush buffers after each logged line
template< typename CharT >
BOOST_LOG_API void basic_text_ostream_backend< CharT >::auto_flush(bool f)
{
    m_pImpl->m_fAutoFlush = f;
}

//! The method writes the message to the sink
template< typename CharT >
BOOST_LOG_API void basic_text_ostream_backend< CharT >::consume(record_view const&, string_type const& message)
{
    typename string_type::const_pointer const p = message.data();
    typename string_type::size_type const s = message.size();
    typename implementation::ostream_sequence::const_iterator
        it = m_pImpl->m_Streams.begin(), end = m_pImpl->m_Streams.end();
    for (; it != end; ++it)
    {
        stream_type* const strm = it->get();
        if (strm->good())
        {
            strm->write(p, static_cast< std::streamsize >(s));
            strm->put(static_cast< char_type >('\n'));

            if (m_pImpl->m_fAutoFlush)
                strm->flush();
        }
    }
}

//! The method flushes the associated streams
template< typename CharT >
BOOST_LOG_API void basic_text_ostream_backend< CharT >::flush()
{
    typename implementation::ostream_sequence::const_iterator
        it = m_pImpl->m_Streams.begin(), end = m_pImpl->m_Streams.end();
    for (; it != end; ++it)
    {
        stream_type* const strm = it->get();
        if (strm->good())
            strm->flush();
    }
}

//! Explicitly instantiate sink backend implementation
#ifdef BOOST_LOG_USE_CHAR
template class basic_text_ostream_backend< char >;
#endif
#ifdef BOOST_LOG_USE_WCHAR_T
template class basic_text_ostream_backend< wchar_t >;
#endif

} // namespace sinks

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>