196 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- SBStream.cpp ----------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "lldb/API/SBStream.h"
 | |
| 
 | |
| #include "lldb/Core/Error.h"
 | |
| #include "lldb/Core/Stream.h"
 | |
| #include "lldb/Core/StreamFile.h"
 | |
| #include "lldb/Core/StreamString.h"
 | |
| 
 | |
| using namespace lldb;
 | |
| using namespace lldb_private;
 | |
| 
 | |
| SBStream::SBStream () :
 | |
|     m_opaque_ap (new StreamString()),
 | |
|     m_is_file (false)
 | |
| {
 | |
| }
 | |
| 
 | |
| SBStream::~SBStream ()
 | |
| {
 | |
| }
 | |
| 
 | |
| bool
 | |
| SBStream::IsValid() const
 | |
| {
 | |
|     return (m_opaque_ap.get() != NULL);
 | |
| }
 | |
| 
 | |
| // If this stream is not redirected to a file, it will maintain a local
 | |
| // cache for the stream data which can be accessed using this accessor.
 | |
| const char *
 | |
| SBStream::GetData ()
 | |
| {
 | |
|     if (m_is_file || m_opaque_ap.get() == NULL)
 | |
|         return NULL;
 | |
|     
 | |
|     return static_cast<StreamString *>(m_opaque_ap.get())->GetData();
 | |
| }
 | |
| 
 | |
| // If this stream is not redirected to a file, it will maintain a local
 | |
| // cache for the stream output whose length can be accessed using this 
 | |
| // accessor.
 | |
| size_t
 | |
| SBStream::GetSize()
 | |
| {
 | |
|     if (m_is_file || m_opaque_ap.get() == NULL)
 | |
|         return 0;
 | |
|     
 | |
|     return static_cast<StreamString *>(m_opaque_ap.get())->GetSize();
 | |
| }
 | |
| 
 | |
| void
 | |
| SBStream::Printf (const char *format, ...)
 | |
| {
 | |
|     if (!format)
 | |
|         return;
 | |
|     va_list args;
 | |
|     va_start (args, format);
 | |
|     ref().PrintfVarArg (format, args);
 | |
|     va_end (args);
 | |
| }
 | |
| 
 | |
| void
 | |
| SBStream::RedirectToFile (const char *path, bool append)
 | |
| {
 | |
|     if (path == nullptr)
 | |
|         return;
 | |
| 
 | |
|     std::string local_data;
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         // See if we have any locally backed data. If so, copy it so we can then
 | |
|         // redirect it to the file so we don't lose the data
 | |
|         if (!m_is_file)
 | |
|             local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
 | |
|     }
 | |
|     StreamFile *stream_file = new StreamFile;
 | |
|     uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
 | |
|     if (append)
 | |
|         open_options |= File::eOpenOptionAppend;
 | |
|     else
 | |
|         open_options |= File::eOpenOptionTruncate;
 | |
|     stream_file->GetFile().Open (path, open_options, lldb::eFilePermissionsFileDefault);
 | |
| 
 | |
|     m_opaque_ap.reset (stream_file);
 | |
| 
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         m_is_file = true;
 | |
| 
 | |
|         // If we had any data locally in our StreamString, then pass that along to 
 | |
|         // the to new file we are redirecting to.
 | |
|         if (!local_data.empty())
 | |
|             m_opaque_ap->Write (&local_data[0], local_data.size());
 | |
|     }
 | |
|     else
 | |
|         m_is_file = false;
 | |
| }
 | |
| 
 | |
| void
 | |
| SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership)
 | |
| {
 | |
|     if (fh == nullptr)
 | |
|         return;
 | |
| 
 | |
|     std::string local_data;
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         // See if we have any locally backed data. If so, copy it so we can then
 | |
|         // redirect it to the file so we don't lose the data
 | |
|         if (!m_is_file)
 | |
|             local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
 | |
|     }
 | |
|     m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership));
 | |
| 
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         m_is_file = true;
 | |
| 
 | |
|         // If we had any data locally in our StreamString, then pass that along to 
 | |
|         // the to new file we are redirecting to.
 | |
|         if (!local_data.empty())
 | |
|             m_opaque_ap->Write (&local_data[0], local_data.size());
 | |
|     }
 | |
|     else
 | |
|         m_is_file = false;
 | |
| }
 | |
| 
 | |
| void
 | |
| SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership)
 | |
| {
 | |
|     std::string local_data;
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         // See if we have any locally backed data. If so, copy it so we can then
 | |
|         // redirect it to the file so we don't lose the data
 | |
|         if (!m_is_file)
 | |
|             local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString());
 | |
|     }
 | |
| 
 | |
|     m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership));
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         m_is_file = true;
 | |
| 
 | |
|         // If we had any data locally in our StreamString, then pass that along to 
 | |
|         // the to new file we are redirecting to.
 | |
|         if (!local_data.empty())
 | |
|             m_opaque_ap->Write (&local_data[0], local_data.size());
 | |
|     }
 | |
|     else
 | |
|         m_is_file = false;
 | |
| 
 | |
| }
 | |
| 
 | |
| lldb_private::Stream *
 | |
| SBStream::operator->()
 | |
| {
 | |
|     return m_opaque_ap.get();
 | |
| }
 | |
| 
 | |
| lldb_private::Stream *
 | |
| SBStream::get()
 | |
| {
 | |
|     return m_opaque_ap.get();
 | |
| }
 | |
| 
 | |
| lldb_private::Stream &
 | |
| SBStream::ref()
 | |
| {
 | |
|     if (m_opaque_ap.get() == NULL)
 | |
|         m_opaque_ap.reset (new StreamString());
 | |
|     return *m_opaque_ap.get();
 | |
| }
 | |
| 
 | |
| void
 | |
| SBStream::Clear ()
 | |
| {
 | |
|     if (m_opaque_ap.get())
 | |
|     {
 | |
|         // See if we have any locally backed data. If so, copy it so we can then
 | |
|         // redirect it to the file so we don't lose the data
 | |
|         if (m_is_file)
 | |
|             m_opaque_ap.reset();
 | |
|         else
 | |
|             static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear();
 | |
|     }
 | |
| }
 |