Index: lldb/include/lldb/Utility/Log.h =================================================================== --- lldb/include/lldb/Utility/Log.h +++ lldb/include/lldb/Utility/Log.h @@ -77,6 +77,19 @@ void *m_baton; }; +class BufferedLogHandler : public LogHandler { +public: + BufferedLogHandler(size_t size, std::shared_ptr delegate); + + void Emit(llvm::StringRef message) override; + +private: + std::shared_ptr m_delegate; + std::unique_ptr m_messages; + const size_t m_size = 0; + size_t m_next_index = 0; +}; + class RotatingLogHandler : public LogHandler { public: RotatingLogHandler(size_t size); Index: lldb/source/Utility/Log.cpp =================================================================== --- lldb/source/Utility/Log.cpp +++ lldb/source/Utility/Log.cpp @@ -355,6 +355,22 @@ m_callback(message.data(), m_baton); } +BufferedLogHandler::BufferedLogHandler(size_t size, + std::shared_ptr delegate) + : m_delegate(delegate), m_messages(std::make_unique(size)), + m_size(size) {} + +void BufferedLogHandler::Emit(llvm::StringRef message) { + m_messages[m_next_index++] = message.str(); + if (m_next_index == m_size) { + for (size_t i = 0; i < m_size; ++i) { + m_delegate->Emit(m_messages[i]); + m_messages[i].clear(); + } + m_next_index = 0; + } +} + RotatingLogHandler::RotatingLogHandler(size_t size) : m_messages(std::make_unique(size)), m_size(size) {} Index: lldb/unittests/Utility/LogTest.cpp =================================================================== --- lldb/unittests/Utility/LogTest.cpp +++ lldb/unittests/Utility/LogTest.cpp @@ -193,6 +193,23 @@ EXPECT_EQ(GetDumpAsString(handler), "bazquxquux"); } +TEST(LogHandlerTest, BufferedLogHandler) { + auto delegate_sp = std::make_shared(); + BufferedLogHandler handler(3, delegate_sp); + + handler.Emit("foo"); + handler.Emit("bar"); + EXPECT_EQ(delegate_sp->m_stream.str(), ""); + handler.Emit("baz"); + EXPECT_EQ(delegate_sp->m_stream.str(), "foobarbaz"); + + handler.Emit("qux"); + handler.Emit("quux"); + EXPECT_EQ(delegate_sp->m_stream.str(), "foobarbaz"); + handler.Emit("quuz"); + EXPECT_EQ(delegate_sp->m_stream.str(), "foobarbazquxquuxquuz"); +} + TEST_F(LogChannelTest, Enable) { EXPECT_EQ(nullptr, GetLog(TestChannel::FOO)); std::string message;