Home | History | Annotate | Download | only in API
      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 
     17 using namespace lldb;
     18 using namespace lldb_private;
     19 
     20 SBStream::SBStream () :
     21     m_opaque_ap (new StreamString()),
     22     m_is_file (false)
     23 {
     24 }
     25 
     26 SBStream::~SBStream ()
     27 {
     28 }
     29 
     30 bool
     31 SBStream::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.
     38 const char *
     39 SBStream::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.
     50 size_t
     51 SBStream::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 
     59 void
     60 SBStream::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 
     70 void
     71 SBStream::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, File::ePermissionsDefault);
     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 
    102 void
    103 SBStream::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 
    128 void
    129 SBStream::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 
    155 lldb_private::Stream *
    156 SBStream::operator->()
    157 {
    158     return m_opaque_ap.get();
    159 }
    160 
    161 lldb_private::Stream *
    162 SBStream::get()
    163 {
    164     return m_opaque_ap.get();
    165 }
    166 
    167 lldb_private::Stream &
    168 SBStream::ref()
    169 {
    170     if (m_opaque_ap.get() == NULL)
    171         m_opaque_ap.reset (new StreamString());
    172     return *m_opaque_ap.get();
    173 }
    174 
    175 void
    176 SBStream::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