File indexing completed on 2025-01-18 09:29:24
0001
0002
0003
0004
0005
0006
0007
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
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 }
0139 }
0140 }
0141
0142 #endif