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