123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /*
- * Copyright Andrey Semashev 2007 - 2013.
- * 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 attachable_sstream_buf.hpp
- * \author Andrey Semashev
- * \date 29.07.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.
- */
- #ifndef BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
- #define BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
- #include <memory>
- #include <string>
- #include <streambuf>
- #include <boost/assert.hpp>
- #include <boost/utility/addressof.hpp>
- #include <boost/log/detail/config.hpp>
- #include <boost/log/detail/header.hpp>
- #ifdef BOOST_HAS_PRAGMA_ONCE
- #pragma once
- #endif
- namespace boost {
- BOOST_LOG_OPEN_NAMESPACE
- namespace aux {
- //! A streambuf that puts the formatted data to an external string
- template<
- typename CharT,
- typename TraitsT = std::char_traits< CharT >,
- typename AllocatorT = std::allocator< CharT >
- >
- class basic_ostringstreambuf :
- public std::basic_streambuf< CharT, TraitsT >
- {
- //! Self type
- typedef basic_ostringstreambuf< CharT, TraitsT, AllocatorT > this_type;
- //! Base type
- typedef std::basic_streambuf< CharT, TraitsT > base_type;
- //! Buffer size
- enum { buffer_size = 16 };
- public:
- //! Character type
- typedef typename base_type::char_type char_type;
- //! Traits type
- typedef typename base_type::traits_type traits_type;
- //! String type
- typedef std::basic_string< char_type, traits_type, AllocatorT > string_type;
- //! Int type
- typedef typename base_type::int_type int_type;
- private:
- //! A reference to the string that will be filled
- string_type* m_Storage;
- //! A buffer used to temporarily store output
- char_type m_Buffer[buffer_size];
- public:
- //! Constructor
- explicit basic_ostringstreambuf() : m_Storage(0)
- {
- base_type::setp(m_Buffer, m_Buffer + (sizeof(m_Buffer) / sizeof(*m_Buffer)));
- }
- //! Constructor
- explicit basic_ostringstreambuf(string_type& storage) : m_Storage(boost::addressof(storage))
- {
- base_type::setp(m_Buffer, m_Buffer + (sizeof(m_Buffer) / sizeof(*m_Buffer)));
- }
- //! Clears the buffer to the initial state
- void clear()
- {
- register char_type* pBase = this->pbase();
- register char_type* pPtr = this->pptr();
- if (pBase != pPtr)
- this->pbump(static_cast< int >(pBase - pPtr));
- }
- //! Detaches the buffer from the string
- void detach()
- {
- if (m_Storage)
- {
- this_type::sync();
- m_Storage = 0;
- }
- }
- //! Attaches the buffer to another string
- void attach(string_type& storage)
- {
- detach();
- m_Storage = boost::addressof(storage);
- }
- //! Returns a pointer to the attached string
- string_type* storage() const { return m_Storage; }
- protected:
- //! Puts all buffered data to the string
- int sync()
- {
- BOOST_ASSERT(m_Storage != 0);
- register char_type* pBase = this->pbase();
- register char_type* pPtr = this->pptr();
- if (pBase != pPtr)
- {
- m_Storage->append(pBase, pPtr);
- this->pbump(static_cast< int >(pBase - pPtr));
- }
- return 0;
- }
- //! Puts an unbuffered character to the string
- int_type overflow(int_type c)
- {
- BOOST_ASSERT(m_Storage != 0);
- basic_ostringstreambuf::sync();
- if (!traits_type::eq_int_type(c, traits_type::eof()))
- {
- m_Storage->push_back(traits_type::to_char_type(c));
- return c;
- }
- else
- return traits_type::not_eof(c);
- }
- //! Puts a character sequence to the string
- std::streamsize xsputn(const char_type* s, std::streamsize n)
- {
- BOOST_ASSERT(m_Storage != 0);
- basic_ostringstreambuf::sync();
- typedef typename string_type::size_type string_size_type;
- register const string_size_type max_storage_left =
- m_Storage->max_size() - m_Storage->size();
- if (static_cast< string_size_type >(n) < max_storage_left)
- {
- m_Storage->append(s, static_cast< string_size_type >(n));
- return n;
- }
- else
- {
- m_Storage->append(s, max_storage_left);
- return static_cast< std::streamsize >(max_storage_left);
- }
- }
- //! Copy constructor (closed)
- BOOST_DELETED_FUNCTION(basic_ostringstreambuf(basic_ostringstreambuf const& that))
- //! Assignment (closed)
- BOOST_DELETED_FUNCTION(basic_ostringstreambuf& operator= (basic_ostringstreambuf const& that))
- };
- } // namespace aux
- BOOST_LOG_CLOSE_NAMESPACE // namespace log
- } // namespace boost
- #include <boost/log/detail/footer.hpp>
- #endif // BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
|