1e2ae97f2SGreg Clayton //===-- SBStream.cpp ----------------------------------------*- C++ -*-===// 2e2ae97f2SGreg Clayton // 3e2ae97f2SGreg Clayton // The LLVM Compiler Infrastructure 4e2ae97f2SGreg Clayton // 5e2ae97f2SGreg Clayton // This file is distributed under the University of Illinois Open Source 6e2ae97f2SGreg Clayton // License. See LICENSE.TXT for details. 7e2ae97f2SGreg Clayton // 8e2ae97f2SGreg Clayton //===----------------------------------------------------------------------===// 9e2ae97f2SGreg Clayton 10e2ae97f2SGreg Clayton #include "lldb/API/SBStream.h" 11e2ae97f2SGreg Clayton 12e2ae97f2SGreg Clayton #include "lldb/Core/Stream.h" 13e2ae97f2SGreg Clayton #include "lldb/Core/StreamFile.h" 14e2ae97f2SGreg Clayton #include "lldb/Core/StreamString.h" 15e2ae97f2SGreg Clayton 16e2ae97f2SGreg Clayton using namespace lldb; 17e2ae97f2SGreg Clayton using namespace lldb_private; 18e2ae97f2SGreg Clayton 19e2ae97f2SGreg Clayton SBStream::SBStream () : 20*f6eaba85SJohnny Chen m_opaque_ap (new StreamString()), 21e2ae97f2SGreg Clayton m_is_file (false) 22e2ae97f2SGreg Clayton { 23e2ae97f2SGreg Clayton } 24e2ae97f2SGreg Clayton 25e2ae97f2SGreg Clayton SBStream::~SBStream () 26e2ae97f2SGreg Clayton { 27e2ae97f2SGreg Clayton } 28e2ae97f2SGreg Clayton 29e2ae97f2SGreg Clayton bool 30e2ae97f2SGreg Clayton SBStream::IsValid() const 31e2ae97f2SGreg Clayton { 32e2ae97f2SGreg Clayton return (m_opaque_ap.get() != NULL); 33e2ae97f2SGreg Clayton } 34e2ae97f2SGreg Clayton 35e2ae97f2SGreg Clayton // If this stream is not redirected to a file, it will maintain a local 36e2ae97f2SGreg Clayton // cache for the stream data which can be accessed using this accessor. 37e2ae97f2SGreg Clayton const char * 38e2ae97f2SGreg Clayton SBStream::GetData () 39e2ae97f2SGreg Clayton { 40e2ae97f2SGreg Clayton if (m_is_file || m_opaque_ap.get() == NULL) 41e2ae97f2SGreg Clayton return NULL; 42e2ae97f2SGreg Clayton 43e2ae97f2SGreg Clayton return static_cast<StreamString *>(m_opaque_ap.get())->GetData(); 44e2ae97f2SGreg Clayton } 45e2ae97f2SGreg Clayton 46e2ae97f2SGreg Clayton // If this stream is not redirected to a file, it will maintain a local 47e2ae97f2SGreg Clayton // cache for the stream output whose length can be accessed using this 48e2ae97f2SGreg Clayton // accessor. 49e2ae97f2SGreg Clayton size_t 50e2ae97f2SGreg Clayton SBStream::GetSize() 51e2ae97f2SGreg Clayton { 52e2ae97f2SGreg Clayton if (m_is_file || m_opaque_ap.get() == NULL) 53e2ae97f2SGreg Clayton return NULL; 54e2ae97f2SGreg Clayton 55e2ae97f2SGreg Clayton return static_cast<StreamString *>(m_opaque_ap.get())->GetSize(); 56e2ae97f2SGreg Clayton } 57e2ae97f2SGreg Clayton 58e2ae97f2SGreg Clayton void 59e2ae97f2SGreg Clayton SBStream::Printf (const char *format, ...) 60e2ae97f2SGreg Clayton { 61e2ae97f2SGreg Clayton va_list args; 62e2ae97f2SGreg Clayton va_start (args, format); 63e2ae97f2SGreg Clayton ref().PrintfVarArg (format, args); 64e2ae97f2SGreg Clayton va_end (args); 65e2ae97f2SGreg Clayton } 66e2ae97f2SGreg Clayton 67e2ae97f2SGreg Clayton void 68e2ae97f2SGreg Clayton SBStream::RedirectToFile (const char *path, bool append) 69e2ae97f2SGreg Clayton { 70e2ae97f2SGreg Clayton std::string local_data; 71e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 72e2ae97f2SGreg Clayton { 73e2ae97f2SGreg Clayton // See if we have any locally backed data. If so, copy it so we can then 74e2ae97f2SGreg Clayton // redirect it to the file so we don't lose the data 75e2ae97f2SGreg Clayton if (!m_is_file) 76e2ae97f2SGreg Clayton local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); 77e2ae97f2SGreg Clayton } 78e2ae97f2SGreg Clayton m_opaque_ap.reset (new StreamFile (path, append ? "a" : "w")); 79e2ae97f2SGreg Clayton 80e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 81e2ae97f2SGreg Clayton { 82e2ae97f2SGreg Clayton m_is_file = true; 83e2ae97f2SGreg Clayton 84e2ae97f2SGreg Clayton // If we had any data locally in our StreamString, then pass that along to 85e2ae97f2SGreg Clayton // the to new file we are redirecting to. 86e2ae97f2SGreg Clayton if (!local_data.empty()) 87e2ae97f2SGreg Clayton m_opaque_ap->Write (&local_data[0], local_data.size()); 88e2ae97f2SGreg Clayton } 89e2ae97f2SGreg Clayton else 90e2ae97f2SGreg Clayton m_is_file = false; 91e2ae97f2SGreg Clayton } 92e2ae97f2SGreg Clayton 93e2ae97f2SGreg Clayton void 94e2ae97f2SGreg Clayton SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership) 95e2ae97f2SGreg Clayton { 96e2ae97f2SGreg Clayton std::string local_data; 97e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 98e2ae97f2SGreg Clayton { 99e2ae97f2SGreg Clayton // See if we have any locally backed data. If so, copy it so we can then 100e2ae97f2SGreg Clayton // redirect it to the file so we don't lose the data 101e2ae97f2SGreg Clayton if (!m_is_file) 102e2ae97f2SGreg Clayton local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); 103e2ae97f2SGreg Clayton } 104e2ae97f2SGreg Clayton m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership)); 105e2ae97f2SGreg Clayton 106e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 107e2ae97f2SGreg Clayton { 108e2ae97f2SGreg Clayton m_is_file = true; 109e2ae97f2SGreg Clayton 110e2ae97f2SGreg Clayton // If we had any data locally in our StreamString, then pass that along to 111e2ae97f2SGreg Clayton // the to new file we are redirecting to. 112e2ae97f2SGreg Clayton if (!local_data.empty()) 113e2ae97f2SGreg Clayton m_opaque_ap->Write (&local_data[0], local_data.size()); 114e2ae97f2SGreg Clayton } 115e2ae97f2SGreg Clayton else 116e2ae97f2SGreg Clayton m_is_file = false; 117e2ae97f2SGreg Clayton } 118e2ae97f2SGreg Clayton 119e2ae97f2SGreg Clayton void 120e2ae97f2SGreg Clayton SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership) 121e2ae97f2SGreg Clayton { 122e2ae97f2SGreg Clayton std::string local_data; 123e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 124e2ae97f2SGreg Clayton { 125e2ae97f2SGreg Clayton // See if we have any locally backed data. If so, copy it so we can then 126e2ae97f2SGreg Clayton // redirect it to the file so we don't lose the data 127e2ae97f2SGreg Clayton if (!m_is_file) 128e2ae97f2SGreg Clayton local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); 129e2ae97f2SGreg Clayton } 130e2ae97f2SGreg Clayton 131e2ae97f2SGreg Clayton m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership)); 132e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 133e2ae97f2SGreg Clayton { 134e2ae97f2SGreg Clayton m_is_file = true; 135e2ae97f2SGreg Clayton 136e2ae97f2SGreg Clayton // If we had any data locally in our StreamString, then pass that along to 137e2ae97f2SGreg Clayton // the to new file we are redirecting to. 138e2ae97f2SGreg Clayton if (!local_data.empty()) 139e2ae97f2SGreg Clayton m_opaque_ap->Write (&local_data[0], local_data.size()); 140e2ae97f2SGreg Clayton } 141e2ae97f2SGreg Clayton else 142e2ae97f2SGreg Clayton m_is_file = false; 143e2ae97f2SGreg Clayton 144e2ae97f2SGreg Clayton } 145e2ae97f2SGreg Clayton 146e2ae97f2SGreg Clayton lldb_private::Stream * 147e2ae97f2SGreg Clayton SBStream::operator->() 148e2ae97f2SGreg Clayton { 149e2ae97f2SGreg Clayton return m_opaque_ap.get(); 150e2ae97f2SGreg Clayton } 151e2ae97f2SGreg Clayton 152e2ae97f2SGreg Clayton lldb_private::Stream * 153e2ae97f2SGreg Clayton SBStream::get() 154e2ae97f2SGreg Clayton { 155e2ae97f2SGreg Clayton return m_opaque_ap.get(); 156e2ae97f2SGreg Clayton } 157e2ae97f2SGreg Clayton 158e2ae97f2SGreg Clayton lldb_private::Stream & 159e2ae97f2SGreg Clayton SBStream::ref() 160e2ae97f2SGreg Clayton { 161e2ae97f2SGreg Clayton if (m_opaque_ap.get() == NULL) 162e2ae97f2SGreg Clayton m_opaque_ap.reset (new StreamString()); 163e2ae97f2SGreg Clayton return *m_opaque_ap.get(); 164e2ae97f2SGreg Clayton } 165e2ae97f2SGreg Clayton 166e2ae97f2SGreg Clayton void 167e2ae97f2SGreg Clayton SBStream::Clear () 168e2ae97f2SGreg Clayton { 169e2ae97f2SGreg Clayton if (m_opaque_ap.get()) 170e2ae97f2SGreg Clayton { 171e2ae97f2SGreg Clayton // See if we have any locally backed data. If so, copy it so we can then 172e2ae97f2SGreg Clayton // redirect it to the file so we don't lose the data 173e2ae97f2SGreg Clayton if (m_is_file) 174e2ae97f2SGreg Clayton m_opaque_ap.reset(); 175e2ae97f2SGreg Clayton else 176e2ae97f2SGreg Clayton static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear(); 177e2ae97f2SGreg Clayton } 178e2ae97f2SGreg Clayton } 179