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