#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 ()
{
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 ()
{
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() {
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)
{
Stream *strm = pos->get();
if (strm)
strm->Flush ();
}
}
virtual int
Write (const void *s, size_t length)
{
Mutex::Locker locker (m_streams_mutex);
if (m_streams.empty())
return 0;
int min_bytes_written = INT_MAX;
collection::iterator pos, end;
for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
{
Stream *strm = pos->get();
if (strm)
{
int bytes_written = strm->Write (s, length);
if (min_bytes_written > bytes_written)
min_bytes_written = bytes_written;
}
}
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);
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;
};
} #endif // #ifndef liblldb_StreamTee_h_