summaryrefslogtreecommitdiff
path: root/libs/glibmm2/glibmm/iochannel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/glibmm2/glibmm/iochannel.cc')
-rw-r--r--libs/glibmm2/glibmm/iochannel.cc687
1 files changed, 687 insertions, 0 deletions
diff --git a/libs/glibmm2/glibmm/iochannel.cc b/libs/glibmm2/glibmm/iochannel.cc
new file mode 100644
index 0000000000..18e434da7a
--- /dev/null
+++ b/libs/glibmm2/glibmm/iochannel.cc
@@ -0,0 +1,687 @@
+// Generated by gtkmmproc -- DO NOT MODIFY!
+
+#include <glibmm/iochannel.h>
+#include <glibmm/private/iochannel_p.h>
+
+// -*- c++ -*-
+/* $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/exceptionhandler.h>
+#include <glibmm/iochannel.h>
+#include <glibmm/utility.h>
+#include <glibmm/main.h>
+#include <glib.h>
+
+
+namespace
+{
+
+// Glib::IOChannel reference counting issues:
+//
+// Normally, you'd expect that the C++ object stays around as long as the
+// C instance does. Also Glib::wrap() usually returns always the same C++
+// wrapper object for a single C instance.
+//
+// Unfortunately it isn't possible to implement these features if we didn't
+// create the underlying GIOChannel. That is, when wrapping existing
+// GIOChannel instances such as returned by e.g. g_io_channel_unix_new() or
+// g_io_channel_new_file(). Neither is there a way to hook up a wrapper
+// object in an existing GIOChannel, nor exists any destroy notification.
+//
+// So that means: If the IOChannel is implemented in C++ -- that is, our
+// GlibmmIOChannel backend is used -- we use the GIOChannel reference
+// counting mechanism. If the IOChannel backend is unknown, then the
+// wrapper instance holds always exactly one reference to the GIOChannel.
+// The wrapper object itself is then managed via our own refcounting
+// mechanism. To do that a utility class ForeignIOChannel is introduced to
+// override reference() and unreference().
+
+class ForeignIOChannel : public Glib::IOChannel
+{
+public:
+ ForeignIOChannel(GIOChannel* gobject, bool take_copy)
+ : Glib::IOChannel(gobject, take_copy), ref_count_(0) {}
+
+ virtual void reference() const;
+ virtual void unreference() const;
+
+private:
+ mutable int ref_count_;
+};
+
+void ForeignIOChannel::reference() const
+{
+ ++ref_count_;
+}
+
+void ForeignIOChannel::unreference() const
+{
+ if (!(--ref_count_)) delete this;
+}
+
+} // anonymous namespace
+
+
+namespace Glib
+{
+
+class GlibmmIOChannel
+{
+public:
+ GIOChannel base;
+ Glib::IOChannel* wrapper;
+
+ static const GIOFuncs vfunc_table;
+
+ static GIOStatus io_read(GIOChannel* channel, char* buf, gsize count,
+ gsize* bytes_read, GError** err);
+
+ static GIOStatus io_write(GIOChannel* channel, const char* buf, gsize count,
+ gsize* bytes_written, GError** err);
+
+ static GIOStatus io_seek (GIOChannel* channel, gint64 offset, GSeekType type, GError** err);
+ static GIOStatus io_close(GIOChannel* channel, GError** err);
+
+ static GSource* io_create_watch(GIOChannel* channel, GIOCondition condition);
+ static void io_free(GIOChannel* channel);
+
+ static GIOStatus io_set_flags(GIOChannel* channel, GIOFlags flags, GError** err);
+ static GIOFlags io_get_flags(GIOChannel* channel);
+};
+
+// static
+const GIOFuncs GlibmmIOChannel::vfunc_table =
+{
+ &GlibmmIOChannel::io_read,
+ &GlibmmIOChannel::io_write,
+ &GlibmmIOChannel::io_seek,
+ &GlibmmIOChannel::io_close,
+ &GlibmmIOChannel::io_create_watch,
+ &GlibmmIOChannel::io_free,
+ &GlibmmIOChannel::io_set_flags,
+ &GlibmmIOChannel::io_get_flags,
+};
+
+
+/**** GLib::IOChannel ******************************************************/
+
+/* Construct a custom C++-implemented IOChannel. GlibmmIOChannel is an
+ * extended GIOChannel struct which allows us to hook up a pointer to this
+ * persistent wrapper instance.
+ */
+IOChannel::IOChannel()
+:
+ gobject_ (static_cast<GIOChannel*>(g_malloc(sizeof(GlibmmIOChannel))))
+{
+ g_io_channel_init(gobject_);
+ gobject_->funcs = const_cast<GIOFuncs*>(&GlibmmIOChannel::vfunc_table);
+
+ reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = this;
+}
+
+/* Construct an IOChannel wrapper for an already created GIOChannel.
+ * See the comment at the top of this file for an explanation of the
+ * problems with this approach.
+ */
+IOChannel::IOChannel(GIOChannel* gobject, bool take_copy)
+:
+ gobject_ (gobject)
+{
+ // This ctor should never be called for GlibmmIOChannel instances.
+ g_assert(gobject != 0);
+ g_assert(gobject->funcs != &GlibmmIOChannel::vfunc_table);
+
+ if(take_copy)
+ g_io_channel_ref(gobject_);
+}
+
+IOChannel::~IOChannel()
+{
+ if(gobject_)
+ {
+ // Check whether this IOChannel is implemented in C++, i.e. whether it
+ // uses our GlibmmIOChannel forwarding backend. Normally, this will never
+ // be true because the wrapper should only be deleted in the io_free()
+ // callback, which clears gobject_ before deleting. But in case the ctor
+ // of a derived class threw an exception the GIOChannel must be destroyed
+ // prematurely.
+ //
+ if(gobject_->funcs == &GlibmmIOChannel::vfunc_table)
+ {
+ // Disconnect the wrapper object so that it won't be deleted twice.
+ reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = 0;
+ }
+
+ GIOChannel *const tmp_gobject = gobject_;
+ gobject_ = 0;
+
+ g_io_channel_unref(tmp_gobject);
+ }
+}
+
+Glib::RefPtr<IOChannel> IOChannel::create_from_file(const std::string& filename, const std::string& mode)
+{
+ GError* error = 0;
+ GIOChannel *const channel = g_io_channel_new_file(filename.c_str(), mode.c_str(), &error);
+
+ if(error)
+ Glib::Error::throw_exception(error);
+
+ return Glib::wrap(channel, false);
+}
+
+Glib::RefPtr<IOChannel> IOChannel::create_from_fd(int fd)
+{
+ return Glib::wrap(g_io_channel_unix_new(fd), false);
+}
+
+#ifdef G_OS_WIN32
+
+Glib::RefPtr<IOChannel> IOChannel::create_from_win32_fd(int fd)
+{
+ return Glib::wrap(g_io_channel_win32_new_fd(fd), false);
+}
+
+Glib::RefPtr<IOChannel> IOChannel::create_from_win32_socket(int socket)
+{
+ return Glib::wrap(g_io_channel_win32_new_socket(socket), false);
+}
+
+#endif /* G_OS_WIN32 */
+
+IOStatus IOChannel::write(const Glib::ustring& str)
+{
+ gsize bytes_written = 0;
+ return write(str.data(), str.bytes(), bytes_written);
+}
+
+IOStatus IOChannel::read_line(Glib::ustring& line)
+{
+ Glib::ScopedPtr<char> buf;
+ GError* error = 0;
+ gsize bytes = 0;
+
+ const GIOStatus status = g_io_channel_read_line(gobj(), buf.addr(), &bytes, 0, &error);
+
+ if(error)
+ Glib::Error::throw_exception(error);
+
+ if(buf.get())
+ line.assign(buf.get(), buf.get() + bytes);
+ else
+ line.erase();
+
+ return (IOStatus) status;
+}
+
+IOStatus IOChannel::read_to_end(Glib::ustring& str)
+{
+ Glib::ScopedPtr<char> buf;
+ GError* error = 0;
+ gsize bytes = 0;
+
+ const GIOStatus status = g_io_channel_read_to_end(gobj(), buf.addr(), &bytes, &error);
+
+ if(error)
+ Glib::Error::throw_exception(error);
+
+ if(buf.get())
+ str.assign(buf.get(), buf.get() + bytes);
+ else
+ str.erase();
+
+ return (IOStatus) status;
+}
+
+IOStatus IOChannel::read(Glib::ustring& str, gsize count)
+{
+ Glib::ScopedPtr<char> buf (g_new(char, count));
+ GError* error = 0;
+ gsize bytes = 0;
+
+ const GIOStatus status = g_io_channel_read_chars(gobj(), buf.get(), count, &bytes, &error);
+
+ if(error)
+ Glib::Error::throw_exception(error);
+
+ if(buf.get())
+ str.assign(buf.get(), buf.get() + bytes);
+ else
+ str.erase();
+
+ return (IOStatus) status;
+}
+
+IOStatus IOChannel::set_encoding(const std::string& encoding)
+{
+ GError* error = 0;
+
+ const GIOStatus status = g_io_channel_set_encoding(
+ gobj(), (encoding.empty()) ? 0 : encoding.c_str(), &error);
+
+ if(error)
+ Glib::Error::throw_exception(error);
+
+ return (IOStatus) status;
+}
+
+std::string IOChannel::get_encoding() const
+{
+ const char *const encoding = g_io_channel_get_encoding(gobject_);
+ return (encoding) ? std::string(encoding) : std::string();
+}
+
+void IOChannel::set_line_term(const std::string& term)
+{
+ if(term.empty())
+ g_io_channel_set_line_term(gobj(), 0, 0);
+ else
+ g_io_channel_set_line_term(gobj(), term.data(), term.size());
+}
+
+std::string IOChannel::get_line_term() const
+{
+ int len = 0;
+ const char *const term = g_io_channel_get_line_term(gobject_, &len);
+
+ return (term) ? std::string(term, len) : std::string();
+}
+
+Glib::RefPtr<IOSource> IOChannel::create_watch(IOCondition condition)
+{
+ // The corresponding unreference() takes place in the dtor
+ // of the Glib::RefPtr<IOChannel> object below.
+ reference();
+ return IOSource::create(Glib::RefPtr<IOChannel>(this), condition);
+}
+
+IOStatus IOChannel::read_vfunc(char*, gsize, gsize&)
+{
+ g_assert_not_reached();
+ return IO_STATUS_ERROR;
+}
+
+IOStatus IOChannel::write_vfunc(const char*, gsize, gsize&)
+{
+ g_assert_not_reached();
+ return IO_STATUS_ERROR;
+}
+
+IOStatus IOChannel::seek_vfunc(gint64, SeekType)
+{
+ g_assert_not_reached();
+ return IO_STATUS_ERROR;
+}
+
+IOStatus IOChannel::close_vfunc()
+{
+ g_assert_not_reached();
+ return IO_STATUS_ERROR;
+}
+
+Glib::RefPtr<Glib::Source> IOChannel::create_watch_vfunc(IOCondition)
+{
+ g_assert_not_reached();
+ return Glib::RefPtr<Glib::Source>();
+}
+
+IOStatus IOChannel::set_flags_vfunc(IOFlags)
+{
+ g_assert_not_reached();
+ return IO_STATUS_ERROR;
+}
+
+IOFlags IOChannel::get_flags_vfunc()
+{
+ g_assert_not_reached();
+ return IOFlags(0);
+}
+
+void IOChannel::reference() const
+{
+ g_io_channel_ref(gobject_);
+}
+
+void IOChannel::unreference() const
+{
+ g_io_channel_unref(gobject_);
+}
+
+Glib::RefPtr<IOChannel> wrap(GIOChannel* gobject, bool take_copy)
+{
+ IOChannel* cpp_object = 0;
+
+ if(gobject)
+ {
+ if(gobject->funcs == &GlibmmIOChannel::vfunc_table)
+ {
+ cpp_object = reinterpret_cast<GlibmmIOChannel*>(gobject)->wrapper;
+
+ if(take_copy && cpp_object)
+ cpp_object->reference();
+ }
+ else
+ {
+ cpp_object = new ForeignIOChannel(gobject, take_copy);
+ cpp_object->reference(); // the refcount is initially 0
+ }
+ }
+
+ return Glib::RefPtr<IOChannel>(cpp_object);
+}
+
+
+/**** Glib::GlibmmIOChannel ************************************************/
+
+// static
+GIOStatus GlibmmIOChannel::io_read(GIOChannel* channel, char* buf, gsize count,
+ gsize* bytes_read, GError** err)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ return (GIOStatus) wrapper->read_vfunc(buf, count, *bytes_read);
+ }
+ catch(Glib::Error& error)
+ {
+ error.propagate(err);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return G_IO_STATUS_ERROR;
+}
+
+// static
+GIOStatus GlibmmIOChannel::io_write(GIOChannel* channel, const char* buf, gsize count,
+ gsize* bytes_written, GError** err)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ return (GIOStatus) wrapper->write_vfunc(buf, count, *bytes_written);
+ }
+ catch(Glib::Error& error)
+ {
+ error.propagate(err);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return G_IO_STATUS_ERROR;
+}
+
+// static
+GIOStatus GlibmmIOChannel::io_seek(GIOChannel* channel, gint64 offset, GSeekType type, GError** err)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ return (GIOStatus) wrapper->seek_vfunc(offset, (SeekType) type);
+ }
+ catch(Glib::Error& error)
+ {
+ error.propagate(err);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return G_IO_STATUS_ERROR;
+}
+
+// static
+GIOStatus GlibmmIOChannel::io_close(GIOChannel* channel, GError** err)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ return (GIOStatus) wrapper->close_vfunc();
+ }
+ catch(Glib::Error& error)
+ {
+ error.propagate(err);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return G_IO_STATUS_ERROR;
+}
+
+// static
+GSource* GlibmmIOChannel::io_create_watch(GIOChannel* channel, GIOCondition condition)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ const Glib::RefPtr<Source> source = wrapper->create_watch_vfunc((IOCondition) condition);
+ return (source) ? source->gobj_copy() : 0;
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return 0;
+}
+
+// static
+void GlibmmIOChannel::io_free(GIOChannel* channel)
+{
+ if(IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper)
+ {
+ wrapper->gobject_ = 0;
+ delete wrapper;
+ }
+
+ g_free(channel);
+}
+
+// static
+GIOStatus GlibmmIOChannel::io_set_flags(GIOChannel* channel, GIOFlags flags, GError** err)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ return (GIOStatus) wrapper->set_flags_vfunc((IOFlags) flags);
+ }
+ catch(Glib::Error& error)
+ {
+ error.propagate(err);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return G_IO_STATUS_ERROR;
+}
+
+// static
+GIOFlags GlibmmIOChannel::io_get_flags(GIOChannel* channel)
+{
+ IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
+
+ try
+ {
+ return (GIOFlags) wrapper->get_flags_vfunc();
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return GIOFlags(0);
+}
+
+} // namespace Glib
+
+
+namespace
+{
+} // anonymous namespace
+
+
+Glib::IOChannelError::IOChannelError(Glib::IOChannelError::Code error_code, const Glib::ustring& error_message)
+:
+ Glib::Error (G_IO_CHANNEL_ERROR, error_code, error_message)
+{}
+
+Glib::IOChannelError::IOChannelError(GError* gobject)
+:
+ Glib::Error (gobject)
+{}
+
+Glib::IOChannelError::Code Glib::IOChannelError::code() const
+{
+ return static_cast<Code>(Glib::Error::code());
+}
+
+void Glib::IOChannelError::throw_func(GError* gobject)
+{
+ throw Glib::IOChannelError(gobject);
+}
+
+
+namespace Glib
+{
+
+
+IOStatus IOChannel::read(gunichar& unichar)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_read_unichar(gobj(), &(unichar), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+IOStatus IOChannel::read(char* buf, gsize count, gsize& bytes_read)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_read_chars(gobj(), buf, count, &(bytes_read), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+IOStatus IOChannel::write(const char* buf, gssize count, gsize& bytes_written)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_write_chars(gobj(), buf, count, &(bytes_written), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+IOStatus IOChannel::write(gunichar unichar)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_write_unichar(gobj(), unichar, &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+IOStatus IOChannel::seek(gint64 offset, SeekType type)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_seek_position(gobj(), offset, ((GSeekType)(type)), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+IOStatus IOChannel::flush()
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_flush(gobj(), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+IOStatus IOChannel::close(bool flush)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_shutdown(gobj(), static_cast<int>(flush), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+gsize IOChannel::get_buffer_size() const
+{
+ return g_io_channel_get_buffer_size(const_cast<GIOChannel*>(gobj()));
+}
+
+void IOChannel::set_buffer_size(gsize size)
+{
+ g_io_channel_set_buffer_size(gobj(), size);
+}
+
+IOFlags IOChannel::get_flags() const
+{
+ return ((IOFlags)(g_io_channel_get_flags(const_cast<GIOChannel*>(gobj()))));
+}
+
+IOStatus IOChannel::set_flags(IOFlags flags)
+{
+ GError *error = 0;
+ IOStatus retvalue = ((IOStatus)(g_io_channel_set_flags(gobj(), ((GIOFlags)(flags)), &(error))));
+ if(error) ::Glib::Error::throw_exception(error);
+ return retvalue;
+}
+
+void IOChannel::set_buffered(bool buffered)
+{
+ g_io_channel_set_buffered(gobj(), static_cast<int>(buffered));
+}
+
+bool IOChannel::get_buffered() const
+{
+ return g_io_channel_get_buffered(const_cast<GIOChannel*>(gobj()));
+}
+
+IOCondition IOChannel::get_buffer_condition() const
+{
+ return ((IOCondition)(g_io_channel_get_buffer_condition(const_cast<GIOChannel*>(gobj()))));
+}
+
+bool IOChannel::get_close_on_unref() const
+{
+ return g_io_channel_get_close_on_unref(const_cast<GIOChannel*>(gobj()));
+}
+
+void IOChannel::set_close_on_unref(bool do_close)
+{
+ g_io_channel_set_close_on_unref(gobj(), static_cast<int>(do_close));
+}
+
+
+} // namespace Glib
+
+