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