• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SBStream()20 SBStream::SBStream () :
21     m_opaque_ap (new StreamString()),
22     m_is_file (false)
23 {
24 }
25 
~SBStream()26 SBStream::~SBStream ()
27 {
28 }
29 
30 bool
IsValid() const31 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 *
GetData()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
GetSize()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
Printf(const char * format,...)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
RedirectToFile(const char * path,bool append)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
RedirectToFileHandle(FILE * fh,bool transfer_fh_ownership)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
RedirectToFileDescriptor(int fd,bool transfer_fh_ownership)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 *
operator ->()156 SBStream::operator->()
157 {
158     return m_opaque_ap.get();
159 }
160 
161 lldb_private::Stream *
get()162 SBStream::get()
163 {
164     return m_opaque_ap.get();
165 }
166 
167 lldb_private::Stream &
ref()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
Clear()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