aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Core/StreamTee.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Core/StreamTee.h')
-rw-r--r--include/lldb/Core/StreamTee.h175
1 files changed, 175 insertions, 0 deletions
diff --git a/include/lldb/Core/StreamTee.h b/include/lldb/Core/StreamTee.h
new file mode 100644
index 000000000000..e2a29a374553
--- /dev/null
+++ b/include/lldb/Core/StreamTee.h
@@ -0,0 +1,175 @@
+//===-- StreamTee.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamTee_h_
+#define liblldb_StreamTee_h_
+
+#include <limits.h>
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class StreamTee : public Stream
+{
+public:
+ StreamTee () :
+ Stream (),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams ()
+ {
+ }
+
+ StreamTee (lldb::StreamSP &stream_sp):
+ Stream (),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams ()
+ {
+ // No need to lock mutex during construction
+ if (stream_sp)
+ m_streams.push_back (stream_sp);
+ }
+
+
+ StreamTee (lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) :
+ Stream (),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams ()
+ {
+ // No need to lock mutex during construction
+ if (stream_sp)
+ m_streams.push_back (stream_sp);
+ if (stream_2_sp)
+ m_streams.push_back (stream_2_sp);
+ }
+
+ StreamTee (const StreamTee &rhs) :
+ Stream (rhs),
+ m_streams_mutex (Mutex::eMutexTypeRecursive),
+ m_streams() // Don't copy until we lock down "rhs"
+ {
+ Mutex::Locker locker (rhs.m_streams_mutex);
+ m_streams = rhs.m_streams;
+ }
+
+ virtual
+ ~StreamTee ()
+ {
+ }
+
+ StreamTee &
+ operator = (const StreamTee &rhs)
+ {
+ if (this != &rhs) {
+ Stream::operator=(rhs);
+ Mutex::Locker lhs_locker (m_streams_mutex);
+ Mutex::Locker rhs_locker (rhs.m_streams_mutex);
+ m_streams = rhs.m_streams;
+ }
+ return *this;
+ }
+
+ virtual void
+ Flush ()
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ collection::iterator pos, end;
+ for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
+ {
+ // Allow for our collection to contain NULL streams. This allows
+ // the StreamTee to be used with hard coded indexes for clients
+ // that might want N total streams with only a few that are set
+ // to valid values.
+ Stream *strm = pos->get();
+ if (strm)
+ strm->Flush ();
+ }
+ }
+
+ virtual size_t
+ Write (const void *s, size_t length)
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ if (m_streams.empty())
+ return 0;
+
+ size_t min_bytes_written = SIZE_MAX;
+ collection::iterator pos, end;
+ for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
+ {
+ // Allow for our collection to contain NULL streams. This allows
+ // the StreamTee to be used with hard coded indexes for clients
+ // that might want N total streams with only a few that are set
+ // to valid values.
+ Stream *strm = pos->get();
+ if (strm)
+ {
+ const size_t bytes_written = strm->Write (s, length);
+ if (min_bytes_written > bytes_written)
+ min_bytes_written = bytes_written;
+ }
+ }
+ if (min_bytes_written == SIZE_MAX)
+ return 0;
+ return min_bytes_written;
+ }
+
+ size_t
+ AppendStream (const lldb::StreamSP &stream_sp)
+ {
+ size_t new_idx = m_streams.size();
+ Mutex::Locker locker (m_streams_mutex);
+ m_streams.push_back (stream_sp);
+ return new_idx;
+ }
+
+ size_t
+ GetNumStreams () const
+ {
+ size_t result = 0;
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ result = m_streams.size();
+ }
+ return result;
+ }
+
+ lldb::StreamSP
+ GetStreamAtIndex (uint32_t idx)
+ {
+ lldb::StreamSP stream_sp;
+ Mutex::Locker locker (m_streams_mutex);
+ if (idx < m_streams.size())
+ stream_sp = m_streams[idx];
+ return stream_sp;
+ }
+
+ void
+ SetStreamAtIndex (uint32_t idx, const lldb::StreamSP& stream_sp)
+ {
+ Mutex::Locker locker (m_streams_mutex);
+ // Resize our stream vector as necessary to fit as many streams
+ // as needed. This also allows this class to be used with hard
+ // coded indexes that can be used contain many streams, not all
+ // of which are valid.
+ if (idx >= m_streams.size())
+ m_streams.resize(idx + 1);
+ m_streams[idx] = stream_sp;
+ }
+
+
+protected:
+ typedef std::vector<lldb::StreamSP> collection;
+ mutable Mutex m_streams_mutex;
+ collection m_streams;
+};
+
+} // namespace lldb_private
+#endif // #ifndef liblldb_StreamTee_h_