diff --git a/CHANGELOG.md b/CHANGELOG.md index 8362765d..1a55780e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Version 200 * Tidy up flat_static_buffer tests * Add more tests for dynamic buffers * Tidy up multi_buffer +* Refactor ostream API Changes: diff --git a/include/boost/beast/core/detail/ostream.hpp b/include/boost/beast/core/detail/ostream.hpp index 3d850ca3..57e4e516 100644 --- a/include/boost/beast/core/detail/ostream.hpp +++ b/include/boost/beast/core/detail/ostream.hpp @@ -12,8 +12,8 @@ #include #include -#include #include +#include #include #include #include @@ -50,7 +50,8 @@ operator<<(std::ostream& os, buffers_helper const& v) { for(auto b : buffers_range(std::ref(v.b_))) - os.write(static_cast(b.data()), b.size()); + os.write(static_cast( + b.data()), b.size()); return os; } @@ -98,55 +99,40 @@ public: ostream_buffer(DynamicBuffer& b) : b_(b) { - prepare(); } int_type overflow(int_type ch) override { - if(! Traits::eq_int_type(ch, Traits::eof())) - { - Traits::assign(*this->pptr(), - static_cast(ch)); - flush(1); - prepare(); - return ch; - } - flush(); - return traits_type::eof(); - } + BOOST_ASSERT(! Traits::eq_int_type( + ch, Traits::eof())); + sync(); - int - sync() override - { - flush(); - prepare(); - return 0; - } - -private: - void - prepare() - { static std::size_t constexpr max_size = 65536; auto const max_prepare = std::min( std::max( 512, b_.capacity() - b_.size()), std::min( max_size, b_.max_size() - b_.size())); + if(max_prepare == 0) + return Traits::eof(); auto const bs = b_.prepare(max_prepare); auto const b = buffers_front(bs); auto const p = static_cast(b.data()); - this->setp(p, - p + b.size() / sizeof(CharT) - 1); + this->setp(p, p + b.size() / sizeof(CharT)); + + BOOST_ASSERT(b_.capacity() > b_.size()); + return this->sputc( + Traits::to_char_type(ch)); } - void - flush(int extra = 0) + int + sync() override { b_.commit( - (this->pptr() - this->pbase() + extra) * - sizeof(CharT)); + (this->pptr() - this->pbase()) * + sizeof(CharT)); + return 0; } }; @@ -180,55 +166,40 @@ public: ostream_buffer(DynamicBuffer& b) : b_(b) { - prepare(); } int_type overflow(int_type ch) override { - if(! Traits::eq_int_type(ch, Traits::eof())) - { - Traits::assign(*this->pptr(), - static_cast(ch)); - flush(1); - prepare(); - return ch; - } - flush(); - return traits_type::eof(); - } + BOOST_ASSERT(! Traits::eq_int_type( + ch, Traits::eof())); + sync(); - int - sync() override - { - flush(); - prepare(); - return 0; - } - -private: - void - prepare() - { static std::size_t constexpr max_size = 65536; auto const max_prepare = std::min( std::max( 512, b_.capacity() - b_.size()), std::min( max_size, b_.max_size() - b_.size())); + if(max_prepare == 0) + return Traits::eof(); auto const bs = b_.prepare(max_prepare); auto const b = buffers_front(bs); auto const p = static_cast(b.data()); - this->setp(p, - p + b.size() / sizeof(CharT) - 1); + this->setp(p, p + b.size() / sizeof(CharT)); + + BOOST_ASSERT(b_.capacity() > b_.size()); + return this->sputc( + Traits::to_char_type(ch)); } - void - flush(int extra = 0) + int + sync() override { b_.commit( - (this->pptr() - this->pbase() + extra) * - sizeof(CharT)); + (this->pptr() - this->pbase()) * + sizeof(CharT)); + return 0; } }; @@ -256,16 +227,14 @@ public: template ostream_helper:: ostream_helper(DynamicBuffer& b) - : std::basic_ostream( - &this->osb_) + : std::basic_ostream(&this->osb_) , osb_(b) { } template ostream_helper:: -ostream_helper( - ostream_helper&& other) +ostream_helper(ostream_helper&& other) : std::basic_ostream(&osb_) , osb_(std::move(other.osb_)) { @@ -304,7 +273,8 @@ public: DynamicBuffer, CharT, Traits, false>>( new ostream_buffer(b)) - , std::basic_ostream(this->member.get()) + , std::basic_ostream( + this->member.get()) { } @@ -312,7 +282,8 @@ public: : ostream_helper_base>( std::move(other)) - , std::basic_ostream(this->member.get()) + , std::basic_ostream( + this->member.get()) { } }; diff --git a/test/beast/core/buffers_adaptor.cpp b/test/beast/core/buffers_adaptor.cpp index 5452c48c..6f73e1b3 100644 --- a/test/beast/core/buffers_adaptor.cpp +++ b/test/beast/core/buffers_adaptor.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/test/beast/core/flat_static_buffer.cpp b/test/beast/core/flat_static_buffer.cpp index a11933c8..306f0a74 100644 --- a/test/beast/core/flat_static_buffer.cpp +++ b/test/beast/core/flat_static_buffer.cpp @@ -13,6 +13,7 @@ #include "buffer_test.hpp" #include +#include #include #include #include diff --git a/test/beast/core/multi_buffer.cpp b/test/beast/core/multi_buffer.cpp index 2b3e1f96..bcdee5b9 100644 --- a/test/beast/core/multi_buffer.cpp +++ b/test/beast/core/multi_buffer.cpp @@ -13,6 +13,7 @@ #include "buffer_test.hpp" #include +#include #include #include #include diff --git a/test/beast/core/ostream.cpp b/test/beast/core/ostream.cpp index 0fffd01d..ccab35be 100644 --- a/test/beast/core/ostream.cpp +++ b/test/beast/core/ostream.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -22,30 +24,53 @@ class ostream_test : public beast::unit_test::suite { public: void - run() override + testOstream() { + string_view const s = "0123456789abcdef"; + BEAST_EXPECT(s.size() == 16); + + // overflow { - multi_buffer b; - auto os = ostream(b); - os << "Hello, world!\n"; - os.flush(); - BEAST_EXPECT(buffers_to_string(b.data()) == "Hello, world!\n"); - auto os2 = std::move(os); - } - { - auto const s = - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef"; - multi_buffer b; + flat_static_buffer<16> b; ostream(b) << s; BEAST_EXPECT(buffers_to_string(b.data()) == s); } + + // max_size + { + flat_static_buffer<16> b; + auto os = ostream(b); + os << s; + os << '*'; + BEAST_EXPECT(os.bad()); + } + + // max_size (exception + { + flat_static_buffer<16> b; + auto os = ostream(b); + os.exceptions(os.badbit); + os << s; + try + { + os << '*'; + fail("missing exception", __FILE__, __LINE__); + } + catch(std::ios_base::failure const&) + { + pass(); + } + catch(...) + { + fail("wrong exception", __FILE__, __LINE__); + } + } + } + + void + run() override + { + testOstream(); } }; diff --git a/test/beast/core/static_buffer.cpp b/test/beast/core/static_buffer.cpp index 5b2d7eb1..dc83df27 100644 --- a/test/beast/core/static_buffer.cpp +++ b/test/beast/core/static_buffer.cpp @@ -13,6 +13,7 @@ #include "buffer_test.hpp" #include +#include #include #include #include