summaryrefslogtreecommitdiff
path: root/glib/glibmm/streamiochannel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'glib/glibmm/streamiochannel.cc')
-rw-r--r--glib/glibmm/streamiochannel.cc188
1 files changed, 188 insertions, 0 deletions
diff --git a/glib/glibmm/streamiochannel.cc b/glib/glibmm/streamiochannel.cc
new file mode 100644
index 00000000..b25a7cec
--- /dev/null
+++ b/glib/glibmm/streamiochannel.cc
@@ -0,0 +1,188 @@
+/* $Id$ */
+
+/* Copyright (C) 2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glibmm/streamiochannel.h>
+#include <glib.h>
+#include <fstream>
+#include <iostream>
+
+GTKMM_USING_STD(ios)
+
+
+namespace Glib
+{
+
+// static
+Glib::RefPtr<StreamIOChannel> StreamIOChannel::create(std::istream& stream)
+{
+ return Glib::RefPtr<StreamIOChannel>(new StreamIOChannel(&stream, 0));
+}
+
+// static
+Glib::RefPtr<StreamIOChannel> StreamIOChannel::create(std::ostream& stream)
+{
+ return Glib::RefPtr<StreamIOChannel>(new StreamIOChannel(0, &stream));
+}
+
+// static
+Glib::RefPtr<StreamIOChannel> StreamIOChannel::create(std::iostream& stream)
+{
+ return Glib::RefPtr<StreamIOChannel>(new StreamIOChannel(&stream, &stream));
+}
+
+StreamIOChannel::StreamIOChannel(std::istream* stream_in, std::ostream* stream_out)
+:
+ stream_in_ (stream_in),
+ stream_out_ (stream_out)
+{
+ get_flags_vfunc(); // initialize GIOChannel flag bits
+}
+
+StreamIOChannel::~StreamIOChannel()
+{}
+
+IOStatus StreamIOChannel::read_vfunc(char* buf, gsize count, gsize& bytes_read)
+{
+ g_return_val_if_fail(stream_in_ != 0, IO_STATUS_ERROR);
+
+ stream_in_->clear();
+ stream_in_->read(buf, count);
+ bytes_read = stream_in_->gcount();
+
+ if(stream_in_->eof())
+ return IO_STATUS_EOF;
+
+ if(stream_in_->fail())
+ throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Reading from stream failed");
+
+ return IO_STATUS_NORMAL;
+}
+
+IOStatus StreamIOChannel::write_vfunc(const char* buf, gsize count, gsize& bytes_written)
+{
+ g_return_val_if_fail(stream_out_ != 0, IO_STATUS_ERROR);
+
+ bytes_written = 0;
+
+ stream_out_->clear();
+ stream_out_->write(buf, count);
+
+ if(stream_out_->fail())
+ throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Writing to stream failed");
+
+ bytes_written = count; // all or nothing ;)
+
+ return IO_STATUS_NORMAL;
+}
+
+IOStatus StreamIOChannel::seek_vfunc(gint64 offset, SeekType type)
+{
+ std::ios::seekdir direction = std::ios::beg;
+
+ switch(type)
+ {
+ case SEEK_TYPE_SET: direction = std::ios::beg; break;
+ case SEEK_TYPE_CUR: direction = std::ios::cur; break;
+ case SEEK_TYPE_END: direction = std::ios::end; break;
+ }
+
+ bool failed = false;
+
+ if(stream_in_)
+ {
+ stream_in_->clear();
+ stream_in_->seekg(offset, direction);
+ failed = stream_in_->fail();
+ }
+ if(stream_out_)
+ {
+ stream_out_->clear();
+ stream_out_->seekp(offset, direction);
+ failed = (failed || stream_out_->fail());
+ }
+
+ if(failed)
+ throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Seeking into stream failed");
+
+ return Glib::IO_STATUS_NORMAL;
+}
+
+IOStatus StreamIOChannel::close_vfunc()
+{
+ bool failed = false;
+
+ if(std::fstream *const stream = dynamic_cast<std::fstream*>(stream_in_))
+ {
+ stream->clear();
+ stream->close();
+ failed = stream->fail();
+ }
+ else if(std::ifstream *const stream = dynamic_cast<std::ifstream*>(stream_in_))
+ {
+ stream->clear();
+ stream->close();
+ failed = stream->fail();
+ }
+ else if(std::ofstream *const stream = dynamic_cast<std::ofstream*>(stream_out_))
+ {
+ stream->clear();
+ stream->close();
+ failed = stream->fail();
+ }
+ else
+ {
+ throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED,
+ "Attempt to close non-file stream");
+ }
+
+ if(failed)
+ throw Glib::Error(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, "Failed to close stream");
+
+ return IO_STATUS_NORMAL;
+}
+
+IOStatus StreamIOChannel::set_flags_vfunc(IOFlags)
+{
+ return IO_STATUS_NORMAL;
+}
+
+IOFlags StreamIOChannel::get_flags_vfunc()
+{
+ gobj()->is_seekable = 1;
+ gobj()->is_readable = (stream_in_ != 0);
+ gobj()->is_writeable = (stream_out_ != 0);
+
+ IOFlags flags = IO_FLAG_IS_SEEKABLE;
+
+ if(stream_in_)
+ flags |= IO_FLAG_IS_READABLE;
+ if(stream_out_)
+ flags |= IO_FLAG_IS_WRITEABLE;
+
+ return flags;
+}
+
+Glib::RefPtr<Glib::Source> StreamIOChannel::create_watch_vfunc(IOCondition)
+{
+ g_warning("Glib::StreamIOChannel::create_watch_vfunc() not implemented");
+ return Glib::RefPtr<Glib::Source>();
+}
+
+} // namespace Glib
+