Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file attachable_sstream_buf.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 29.07.2007 Chris@16: * Chris@16: * \brief This header is the Boost.Log library implementation, see the library documentation Chris@16: * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: //! A streambuf that puts the formatted data to an external string Chris@16: template< Chris@16: typename CharT, Chris@16: typename TraitsT = std::char_traits< CharT >, Chris@16: typename AllocatorT = std::allocator< CharT > Chris@16: > Chris@16: class basic_ostringstreambuf : Chris@16: public std::basic_streambuf< CharT, TraitsT > Chris@16: { Chris@16: //! Self type Chris@16: typedef basic_ostringstreambuf< CharT, TraitsT, AllocatorT > this_type; Chris@16: //! Base type Chris@16: typedef std::basic_streambuf< CharT, TraitsT > base_type; Chris@16: Chris@16: //! Buffer size Chris@16: enum { buffer_size = 16 }; Chris@16: Chris@16: public: Chris@16: //! Character type Chris@16: typedef typename base_type::char_type char_type; Chris@16: //! Traits type Chris@16: typedef typename base_type::traits_type traits_type; Chris@16: //! String type Chris@16: typedef std::basic_string< char_type, traits_type, AllocatorT > string_type; Chris@16: //! Int type Chris@16: typedef typename base_type::int_type int_type; Chris@16: Chris@16: private: Chris@16: //! A reference to the string that will be filled Chris@16: string_type* m_Storage; Chris@16: //! A buffer used to temporarily store output Chris@16: char_type m_Buffer[buffer_size]; Chris@16: Chris@16: public: Chris@16: //! Constructor Chris@16: explicit basic_ostringstreambuf() : m_Storage(0) Chris@16: { Chris@16: base_type::setp(m_Buffer, m_Buffer + (sizeof(m_Buffer) / sizeof(*m_Buffer))); Chris@16: } Chris@16: //! Constructor Chris@16: explicit basic_ostringstreambuf(string_type& storage) : m_Storage(boost::addressof(storage)) Chris@16: { Chris@16: base_type::setp(m_Buffer, m_Buffer + (sizeof(m_Buffer) / sizeof(*m_Buffer))); Chris@16: } Chris@16: Chris@16: //! Clears the buffer to the initial state Chris@16: void clear() Chris@16: { Chris@101: char_type* pBase = this->pbase(); Chris@101: char_type* pPtr = this->pptr(); Chris@16: if (pBase != pPtr) Chris@16: this->pbump(static_cast< int >(pBase - pPtr)); Chris@16: } Chris@16: Chris@16: //! Detaches the buffer from the string Chris@16: void detach() Chris@16: { Chris@16: if (m_Storage) Chris@16: { Chris@16: this_type::sync(); Chris@16: m_Storage = 0; Chris@16: } Chris@16: } Chris@16: Chris@16: //! Attaches the buffer to another string Chris@16: void attach(string_type& storage) Chris@16: { Chris@16: detach(); Chris@16: m_Storage = boost::addressof(storage); Chris@16: } Chris@16: Chris@16: //! Returns a pointer to the attached string Chris@16: string_type* storage() const { return m_Storage; } Chris@16: Chris@16: protected: Chris@16: //! Puts all buffered data to the string Chris@16: int sync() Chris@16: { Chris@16: BOOST_ASSERT(m_Storage != 0); Chris@101: char_type* pBase = this->pbase(); Chris@101: char_type* pPtr = this->pptr(); Chris@16: if (pBase != pPtr) Chris@16: { Chris@16: m_Storage->append(pBase, pPtr); Chris@16: this->pbump(static_cast< int >(pBase - pPtr)); Chris@16: } Chris@16: return 0; Chris@16: } Chris@16: //! Puts an unbuffered character to the string Chris@16: int_type overflow(int_type c) Chris@16: { Chris@16: BOOST_ASSERT(m_Storage != 0); Chris@16: basic_ostringstreambuf::sync(); Chris@16: if (!traits_type::eq_int_type(c, traits_type::eof())) Chris@16: { Chris@16: m_Storage->push_back(traits_type::to_char_type(c)); Chris@16: return c; Chris@16: } Chris@16: else Chris@16: return traits_type::not_eof(c); Chris@16: } Chris@16: //! Puts a character sequence to the string Chris@16: std::streamsize xsputn(const char_type* s, std::streamsize n) Chris@16: { Chris@16: BOOST_ASSERT(m_Storage != 0); Chris@16: basic_ostringstreambuf::sync(); Chris@16: typedef typename string_type::size_type string_size_type; Chris@101: const string_size_type max_storage_left = Chris@16: m_Storage->max_size() - m_Storage->size(); Chris@16: if (static_cast< string_size_type >(n) < max_storage_left) Chris@16: { Chris@16: m_Storage->append(s, static_cast< string_size_type >(n)); Chris@16: return n; Chris@16: } Chris@16: else Chris@16: { Chris@16: m_Storage->append(s, max_storage_left); Chris@16: return static_cast< std::streamsize >(max_storage_left); Chris@16: } Chris@16: } Chris@16: Chris@16: //! Copy constructor (closed) Chris@16: BOOST_DELETED_FUNCTION(basic_ostringstreambuf(basic_ostringstreambuf const& that)) Chris@16: //! Assignment (closed) Chris@16: BOOST_DELETED_FUNCTION(basic_ostringstreambuf& operator= (basic_ostringstreambuf const& that)) Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_