+extern void ui_file_write (struct ui_file *file, const char *buf,
+ long length_buf);
+
+extern void ui_file_write_async_safe (struct ui_file *file, const char *buf,
+ long length_buf);
+
+extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
+
+/* A std::string-based ui_file. Can be used as a scratch buffer for
+ collecting output. */
+
+class string_file : public ui_file
+{
+public:
+ string_file () {}
+ ~string_file () override;
+
+ /* Override ui_file methods. */
+
+ void write (const char *buf, long length_buf) override;
+
+ long read (char *buf, long length_buf) override
+ { gdb_assert_not_reached ("a string_file is not readable"); }
+
+ /* string_file-specific public API. */
+
+ /* Accesses the std::string containing the entire output collected
+ so far.
+
+ Returns a non-const reference so that it's easy to move the
+ string contents out of the string_file. E.g.:
+
+ string_file buf;
+ buf.printf (....);
+ buf.printf (....);
+ return std::move (buf.string ());
+ */
+ std::string &string () { return m_string; }
+
+ /* Provide a few convenience methods with the same API as the
+ underlying std::string. */
+ const char *data () const { return m_string.data (); }
+ const char *c_str () const { return m_string.c_str (); }
+ size_t size () const { return m_string.size (); }
+ bool empty () const { return m_string.empty (); }
+ void clear () { return m_string.clear (); }
+
+private:
+ /* The internal buffer. */
+ std::string m_string;
+};
+
+/* A ui_file implementation that maps directly onto <stdio.h>'s FILE.
+ A stdio_file can either own its underlying file, or not. If it
+ owns the file, then destroying the stdio_file closes the underlying
+ file, otherwise it is left open. */
+
+class stdio_file : public ui_file
+{
+public:
+ /* Create a ui_file from a previously opened FILE. CLOSE_P
+ indicates whether the underlying file should be closed when the
+ stdio_file is destroyed. */
+ explicit stdio_file (FILE *file, bool close_p = false);
+
+ /* Create an stdio_file that is not managing any file yet. Call
+ open to actually open something. */
+ stdio_file ();
+
+ ~stdio_file () override;
+
+ /* Open NAME in mode MODE, and own the resulting file. Returns true
+ on success, false otherwise. If the stdio_file previously owned
+ a file, it is closed. */
+ bool open (const char *name, const char *mode);
+
+ void flush () override;
+
+ void write (const char *buf, long length_buf) override;
+
+ void write_async_safe (const char *buf, long length_buf) override;
+
+ void puts (const char *) override;
+
+ long read (char *buf, long length_buf) override;
+
+ bool isatty () override;
+
+private:
+ /* Sets the internal stream to FILE, and saves the FILE's file
+ descriptor in M_FD. */
+ void set_stream (FILE *file);
+
+ /* The file. */
+ FILE *m_file;