blob: f50334f7418990f4e6cdee11689ee89c1eb096ea [file] [log] [blame]
Greg Claytone2ae97f2010-09-17 17:42:16 +00001//===-- 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
Greg Clayton51b1e2d2011-02-09 01:08:52 +000012#include "lldb/Core/Error.h"
Greg Claytone2ae97f2010-09-17 17:42:16 +000013#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 () :
Johnny Chenf6eaba82010-12-11 01:20:39 +000021 m_opaque_ap (new StreamString()),
Greg Claytone2ae97f2010-09-17 17:42:16 +000022 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)
Bill Wendling60fd91f2012-04-03 04:14:31 +000054 return 0;
Greg Claytone2ae97f2010-09-17 17:42:16 +000055
56 return static_cast<StreamString *>(m_opaque_ap.get())->GetSize();
57}
58
59void
60SBStream::Printf (const char *format, ...)
61{
Johnny Chen4f8189b2011-12-20 00:41:28 +000062 if (!format)
63 return;
Greg Claytone2ae97f2010-09-17 17:42:16 +000064 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{
Zachary Turnere2dcbd02015-01-14 18:34:35 +000073 if (path == nullptr)
74 return;
75
Greg Claytone2ae97f2010-09-17 17:42:16 +000076 std::string local_data;
77 if (m_opaque_ap.get())
78 {
79 // See if we have any locally backed data. If so, copy it so we can then
80 // redirect it to the file so we don't lose the data
81 if (!m_is_file)
82 local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
83 }
Greg Clayton51b1e2d2011-02-09 01:08:52 +000084 StreamFile *stream_file = new StreamFile;
85 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
86 if (append)
87 open_options |= File::eOpenOptionAppend;
Greg Clayton06357c92014-07-30 17:38:47 +000088 else
89 open_options |= File::eOpenOptionTruncate;
Greg Claytonfbb76342013-11-20 21:07:01 +000090 stream_file->GetFile().Open (path, open_options, lldb::eFilePermissionsFileDefault);
Greg Clayton51b1e2d2011-02-09 01:08:52 +000091
92 m_opaque_ap.reset (stream_file);
Greg Claytone2ae97f2010-09-17 17:42:16 +000093
94 if (m_opaque_ap.get())
95 {
96 m_is_file = true;
97
98 // If we had any data locally in our StreamString, then pass that along to
99 // the to new file we are redirecting to.
100 if (!local_data.empty())
101 m_opaque_ap->Write (&local_data[0], local_data.size());
102 }
103 else
104 m_is_file = false;
105}
106
107void
108SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership)
109{
Zachary Turnere2dcbd02015-01-14 18:34:35 +0000110 if (fh == nullptr)
111 return;
112
Greg Claytone2ae97f2010-09-17 17:42:16 +0000113 std::string local_data;
114 if (m_opaque_ap.get())
115 {
116 // See if we have any locally backed data. If so, copy it so we can then
117 // redirect it to the file so we don't lose the data
118 if (!m_is_file)
119 local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
120 }
121 m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership));
122
123 if (m_opaque_ap.get())
124 {
125 m_is_file = true;
126
127 // If we had any data locally in our StreamString, then pass that along to
128 // the to new file we are redirecting to.
129 if (!local_data.empty())
130 m_opaque_ap->Write (&local_data[0], local_data.size());
131 }
132 else
133 m_is_file = false;
134}
135
136void
137SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership)
138{
139 std::string local_data;
140 if (m_opaque_ap.get())
141 {
142 // See if we have any locally backed data. If so, copy it so we can then
143 // redirect it to the file so we don't lose the data
144 if (!m_is_file)
145 local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
146 }
147
148 m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership));
149 if (m_opaque_ap.get())
150 {
151 m_is_file = true;
152
153 // If we had any data locally in our StreamString, then pass that along to
154 // the to new file we are redirecting to.
155 if (!local_data.empty())
156 m_opaque_ap->Write (&local_data[0], local_data.size());
157 }
158 else
159 m_is_file = false;
160
161}
162
163lldb_private::Stream *
164SBStream::operator->()
165{
166 return m_opaque_ap.get();
167}
168
169lldb_private::Stream *
170SBStream::get()
171{
172 return m_opaque_ap.get();
173}
174
175lldb_private::Stream &
176SBStream::ref()
177{
178 if (m_opaque_ap.get() == NULL)
179 m_opaque_ap.reset (new StreamString());
180 return *m_opaque_ap.get();
181}
182
183void
184SBStream::Clear ()
185{
186 if (m_opaque_ap.get())
187 {
188 // See if we have any locally backed data. If so, copy it so we can then
189 // redirect it to the file so we don't lose the data
190 if (m_is_file)
191 m_opaque_ap.reset();
192 else
193 static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear();
194 }
195}