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/Stream.h"
13 #include "lldb/Core/StreamFile.h"
14 #include "lldb/Core/StreamString.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 SBStream::SBStream () :
20     m_opaque_ap (new StreamString()),
21     m_is_file (false)
22 {
23 }
24 
25 SBStream::~SBStream ()
26 {
27 }
28 
29 bool
30 SBStream::IsValid() const
31 {
32     return (m_opaque_ap.get() != NULL);
33 }
34 
35 // If this stream is not redirected to a file, it will maintain a local
36 // cache for the stream data which can be accessed using this accessor.
37 const char *
38 SBStream::GetData ()
39 {
40     if (m_is_file || m_opaque_ap.get() == NULL)
41         return NULL;
42 
43     return static_cast<StreamString *>(m_opaque_ap.get())->GetData();
44 }
45 
46 // If this stream is not redirected to a file, it will maintain a local
47 // cache for the stream output whose length can be accessed using this
48 // accessor.
49 size_t
50 SBStream::GetSize()
51 {
52     if (m_is_file || m_opaque_ap.get() == NULL)
53         return NULL;
54 
55     return static_cast<StreamString *>(m_opaque_ap.get())->GetSize();
56 }
57 
58 void
59 SBStream::Printf (const char *format, ...)
60 {
61     va_list args;
62     va_start (args, format);
63     ref().PrintfVarArg (format, args);
64     va_end (args);
65 }
66 
67 void
68 SBStream::RedirectToFile (const char *path, bool append)
69 {
70     std::string local_data;
71     if (m_opaque_ap.get())
72     {
73         // See if we have any locally backed data. If so, copy it so we can then
74         // redirect it to the file so we don't lose the data
75         if (!m_is_file)
76             local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
77     }
78     m_opaque_ap.reset (new StreamFile (path, append ? "a" : "w"));
79 
80     if (m_opaque_ap.get())
81     {
82         m_is_file = true;
83 
84         // If we had any data locally in our StreamString, then pass that along to
85         // the to new file we are redirecting to.
86         if (!local_data.empty())
87             m_opaque_ap->Write (&local_data[0], local_data.size());
88     }
89     else
90         m_is_file = false;
91 }
92 
93 void
94 SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership)
95 {
96     std::string local_data;
97     if (m_opaque_ap.get())
98     {
99         // See if we have any locally backed data. If so, copy it so we can then
100         // redirect it to the file so we don't lose the data
101         if (!m_is_file)
102             local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
103     }
104     m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership));
105 
106     if (m_opaque_ap.get())
107     {
108         m_is_file = true;
109 
110         // If we had any data locally in our StreamString, then pass that along to
111         // the to new file we are redirecting to.
112         if (!local_data.empty())
113             m_opaque_ap->Write (&local_data[0], local_data.size());
114     }
115     else
116         m_is_file = false;
117 }
118 
119 void
120 SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership)
121 {
122     std::string local_data;
123     if (m_opaque_ap.get())
124     {
125         // See if we have any locally backed data. If so, copy it so we can then
126         // redirect it to the file so we don't lose the data
127         if (!m_is_file)
128             local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
129     }
130 
131     m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership));
132     if (m_opaque_ap.get())
133     {
134         m_is_file = true;
135 
136         // If we had any data locally in our StreamString, then pass that along to
137         // the to new file we are redirecting to.
138         if (!local_data.empty())
139             m_opaque_ap->Write (&local_data[0], local_data.size());
140     }
141     else
142         m_is_file = false;
143 
144 }
145 
146 lldb_private::Stream *
147 SBStream::operator->()
148 {
149     return m_opaque_ap.get();
150 }
151 
152 lldb_private::Stream *
153 SBStream::get()
154 {
155     return m_opaque_ap.get();
156 }
157 
158 lldb_private::Stream &
159 SBStream::ref()
160 {
161     if (m_opaque_ap.get() == NULL)
162         m_opaque_ap.reset (new StreamString());
163     return *m_opaque_ap.get();
164 }
165 
166 void
167 SBStream::Clear ()
168 {
169     if (m_opaque_ap.get())
170     {
171         // See if we have any locally backed data. If so, copy it so we can then
172         // redirect it to the file so we don't lose the data
173         if (m_is_file)
174             m_opaque_ap.reset();
175         else
176             static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear();
177     }
178 }
179