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