Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:24

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_DETAIL_STATIC_OSTREAM_HPP
0011 #define BOOST_BEAST_DETAIL_STATIC_OSTREAM_HPP
0012 
0013 #include <locale>
0014 #include <ostream>
0015 #include <streambuf>
0016 
0017 namespace boost {
0018 namespace beast {
0019 namespace detail {
0020 
0021 // http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
0022 
0023 class static_ostream_buffer
0024     : public std::basic_streambuf<char>
0025 {
0026     using CharT = char;
0027     using Traits = std::char_traits<CharT>;
0028     using int_type = typename
0029         std::basic_streambuf<CharT, Traits>::int_type;
0030     using traits_type = typename
0031         std::basic_streambuf<CharT, Traits>::traits_type;
0032 
0033     char* data_;
0034     std::size_t size_;
0035     std::size_t len_ = 0;
0036     std::string s_;
0037 
0038 public:
0039     static_ostream_buffer(static_ostream_buffer&&) = delete;
0040     static_ostream_buffer(static_ostream_buffer const&) = delete;
0041 
0042     static_ostream_buffer(char* data, std::size_t size)
0043         : data_(data)
0044         , size_(size)
0045     {
0046         this->setp(data_, data_ + size - 1);
0047     }
0048 
0049     ~static_ostream_buffer() noexcept
0050     {
0051     }
0052 
0053     string_view
0054     str() const
0055     {
0056         if(! s_.empty())
0057             return {s_.data(), len_};
0058         return {data_, len_};
0059     }
0060 
0061     int_type
0062     overflow(int_type ch) override
0063     {
0064         if(! Traits::eq_int_type(ch, Traits::eof()))
0065         {
0066             Traits::assign(*this->pptr(),
0067                 static_cast<CharT>(ch));
0068             flush(1);
0069             prepare();
0070             return ch;
0071         }
0072         flush();
0073         return traits_type::eof();
0074     }
0075 
0076     int
0077     sync() override
0078     {
0079         flush();
0080         prepare();
0081         return 0;
0082     }
0083 
0084 private:
0085     void
0086     prepare()
0087     {
0088         static auto const growth_factor = 1.5;
0089 
0090         if(len_ < size_ - 1)
0091         {
0092             this->setp(
0093                 data_ + len_, data_ + size_ - 2);
0094             return;
0095         }
0096         if(s_.empty())
0097         {
0098             s_.resize(static_cast<std::size_t>(
0099                 growth_factor * len_));
0100             Traits::copy(&s_[0], data_, len_);
0101         }
0102         else
0103         {
0104             s_.resize(static_cast<std::size_t>(
0105                 growth_factor * len_));
0106         }
0107         this->setp(&s_[len_], &s_[len_] +
0108             s_.size() - len_ - 1);
0109     }
0110 
0111     void
0112     flush(int extra = 0)
0113     {
0114         len_ += static_cast<std::size_t>(
0115             this->pptr() - this->pbase() + extra);
0116     }
0117 };
0118 
0119 class static_ostream : public std::basic_ostream<char>
0120 {
0121     static_ostream_buffer osb_;
0122 
0123 public:
0124     static_ostream(char* data, std::size_t size)
0125         : std::basic_ostream<char>(&this->osb_)
0126         , osb_(data, size)
0127     {
0128         imbue(std::locale::classic());
0129     }
0130 
0131     string_view
0132     str() const
0133     {
0134         return osb_.str();
0135     }
0136 };
0137 
0138 } // detail
0139 } // beast
0140 } // boost
0141 
0142 #endif