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