/* $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 #include #include #include GLIBMM_USING_STD(ios) namespace Glib { // static Glib::RefPtr StreamIOChannel::create(std::istream& stream) { return Glib::RefPtr(new StreamIOChannel(&stream, 0)); } // static Glib::RefPtr StreamIOChannel::create(std::ostream& stream) { return Glib::RefPtr(new StreamIOChannel(0, &stream)); } // static Glib::RefPtr StreamIOChannel::create(std::iostream& stream) { return Glib::RefPtr(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(stream_in_)) { stream->clear(); stream->close(); failed = stream->fail(); } else if(std::ifstream *const stream = dynamic_cast(stream_in_)) { stream->clear(); stream->close(); failed = stream->fail(); } else if(std::ofstream *const stream = dynamic_cast(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 StreamIOChannel::create_watch_vfunc(IOCondition) { g_warning("Glib::StreamIOChannel::create_watch_vfunc() not implemented"); return Glib::RefPtr(); } } // namespace Glib