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