blob: 661c0f0a3c3a2d9b2760cec2a3c7927de22e03c4 [file] [log] [blame]
Greg Claytonab7b39c2010-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 Clayton58928562011-02-09 01:08:52 +000012#include "lldb/Core/Error.h"
Greg Claytonab7b39c2010-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 Chene5791dd2010-12-11 01:20:39 +000021 m_opaque_ap (new StreamString()),
Greg Claytonab7b39c2010-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)
54 return NULL;
55
56 return static_cast<StreamString *>(m_opaque_ap.get())->GetSize();
57}
58
59void
60SBStream::Printf (const char *format, ...)
61{
62 va_list args;
63 va_start (args, format);
64 ref().PrintfVarArg (format, args);
65 va_end (args);
66}
67
68void
69SBStream::RedirectToFile (const char *path, bool append)
70{
71 std::string local_data;
72 if (m_opaque_ap.get())
73 {
74 // See if we have any locally backed data. If so, copy it so we can then
75 // redirect it to the file so we don't lose the data
76 if (!m_is_file)
77 local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
78 }
Greg Clayton58928562011-02-09 01:08:52 +000079 StreamFile *stream_file = new StreamFile;
80 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
81 if (append)
82 open_options |= File::eOpenOptionAppend;
83 stream_file->GetFile().Open (path, open_options, File::ePermissionsDefault);
84
85 m_opaque_ap.reset (stream_file);
Greg Claytonab7b39c2010-09-17 17:42:16 +000086
87 if (m_opaque_ap.get())
88 {
89 m_is_file = true;
90
91 // If we had any data locally in our StreamString, then pass that along to
92 // the to new file we are redirecting to.
93 if (!local_data.empty())
94 m_opaque_ap->Write (&local_data[0], local_data.size());
95 }
96 else
97 m_is_file = false;
98}
99
100void
101SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership)
102{
103 std::string local_data;
104 if (m_opaque_ap.get())
105 {
106 // See if we have any locally backed data. If so, copy it so we can then
107 // redirect it to the file so we don't lose the data
108 if (!m_is_file)
109 local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
110 }
111 m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership));
112
113 if (m_opaque_ap.get())
114 {
115 m_is_file = true;
116
117 // If we had any data locally in our StreamString, then pass that along to
118 // the to new file we are redirecting to.
119 if (!local_data.empty())
120 m_opaque_ap->Write (&local_data[0], local_data.size());
121 }
122 else
123 m_is_file = false;
124}
125
126void
127SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership)
128{
129 std::string local_data;
130 if (m_opaque_ap.get())
131 {
132 // See if we have any locally backed data. If so, copy it so we can then
133 // redirect it to the file so we don't lose the data
134 if (!m_is_file)
135 local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
136 }
137
138 m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership));
139 if (m_opaque_ap.get())
140 {
141 m_is_file = true;
142
143 // If we had any data locally in our StreamString, then pass that along to
144 // the to new file we are redirecting to.
145 if (!local_data.empty())
146 m_opaque_ap->Write (&local_data[0], local_data.size());
147 }
148 else
149 m_is_file = false;
150
151}
152
153lldb_private::Stream *
154SBStream::operator->()
155{
156 return m_opaque_ap.get();
157}
158
159lldb_private::Stream *
160SBStream::get()
161{
162 return m_opaque_ap.get();
163}
164
165lldb_private::Stream &
166SBStream::ref()
167{
168 if (m_opaque_ap.get() == NULL)
169 m_opaque_ap.reset (new StreamString());
170 return *m_opaque_ap.get();
171}
172
173void
174SBStream::Clear ()
175{
176 if (m_opaque_ap.get())
177 {
178 // See if we have any locally backed data. If so, copy it so we can then
179 // redirect it to the file so we don't lose the data
180 if (m_is_file)
181 m_opaque_ap.reset();
182 else
183 static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear();
184 }
185}