advance compilation to include plugin_ui.cc
[ardour.git] / libs / glibmm2 / glibmm / iochannel.cc
1 // Generated by gtkmmproc -- DO NOT MODIFY!
2
3 #include <glibmm/iochannel.h>
4 #include <glibmm/private/iochannel_p.h>
5
6 // -*- c++ -*-
7 /* $Id$ */
8
9 /* Copyright (C) 2002 The gtkmm Development Team
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the Free
23  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include <glibmm/exceptionhandler.h>
27 #include <glibmm/iochannel.h>
28 #include <glibmm/utility.h>
29 #include <glibmm/main.h>
30 #include <glib.h>
31
32
33 namespace
34 {
35
36 // Glib::IOChannel reference counting issues:
37 //
38 // Normally, you'd expect that the C++ object stays around as long as the
39 // C instance does.  Also Glib::wrap() usually returns always the same C++
40 // wrapper object for a single C instance.
41 //
42 // Unfortunately it isn't possible to implement these features if we didn't
43 // create the underlying GIOChannel.  That is, when wrapping existing
44 // GIOChannel instances such as returned by e.g. g_io_channel_unix_new() or
45 // g_io_channel_new_file().  Neither is there a way to hook up a wrapper
46 // object in an existing GIOChannel, nor exists any destroy notification.
47 //
48 // So that means:  If the IOChannel is implemented in C++ -- that is, our
49 // GlibmmIOChannel backend is used -- we use the GIOChannel reference
50 // counting mechanism.  If the IOChannel backend is unknown, then the
51 // wrapper instance holds always exactly one reference to the GIOChannel.
52 // The wrapper object itself is then managed via our own refcounting
53 // mechanism.  To do that a utility class ForeignIOChannel is introduced to
54 // override reference() and unreference().
55
56 class ForeignIOChannel : public Glib::IOChannel
57 {
58 public:
59   ForeignIOChannel(GIOChannel* gobject, bool take_copy)
60     : Glib::IOChannel(gobject, take_copy), ref_count_(0) {}
61
62   virtual void reference()   const;
63   virtual void unreference() const;
64
65 private:
66   mutable int ref_count_;
67 };
68
69 void ForeignIOChannel::reference() const
70 {
71   ++ref_count_;
72 }
73
74 void ForeignIOChannel::unreference() const
75 {
76   if (!(--ref_count_)) delete this;
77 }
78
79 } // anonymous namespace
80
81
82 namespace Glib
83 {
84
85 class GlibmmIOChannel
86 {
87 public:
88   GIOChannel        base;
89   Glib::IOChannel*  wrapper;
90
91   static const GIOFuncs vfunc_table;
92
93   static GIOStatus io_read(GIOChannel* channel, char* buf, gsize count,
94                            gsize* bytes_read, GError** err);
95
96   static GIOStatus io_write(GIOChannel* channel, const char* buf, gsize count,
97                             gsize* bytes_written, GError** err);
98
99   static GIOStatus io_seek (GIOChannel* channel, gint64 offset, GSeekType type, GError** err);
100   static GIOStatus io_close(GIOChannel* channel, GError** err);
101
102   static GSource*  io_create_watch(GIOChannel* channel, GIOCondition condition);
103   static void      io_free(GIOChannel* channel);
104
105   static GIOStatus io_set_flags(GIOChannel* channel, GIOFlags flags, GError** err);
106   static GIOFlags  io_get_flags(GIOChannel* channel);
107 };
108
109 // static
110 const GIOFuncs GlibmmIOChannel::vfunc_table =
111 {
112   &GlibmmIOChannel::io_read,
113   &GlibmmIOChannel::io_write,
114   &GlibmmIOChannel::io_seek,
115   &GlibmmIOChannel::io_close,
116   &GlibmmIOChannel::io_create_watch,
117   &GlibmmIOChannel::io_free,
118   &GlibmmIOChannel::io_set_flags,
119   &GlibmmIOChannel::io_get_flags,
120 };
121
122
123 /**** GLib::IOChannel ******************************************************/
124
125 /* Construct a custom C++-implemented IOChannel.  GlibmmIOChannel is an
126  * extended GIOChannel struct which allows us to hook up a pointer to this
127  * persistent wrapper instance.
128  */
129 IOChannel::IOChannel()
130 :
131   gobject_ (static_cast<GIOChannel*>(g_malloc(sizeof(GlibmmIOChannel))))
132 {
133   g_io_channel_init(gobject_);
134   gobject_->funcs = const_cast<GIOFuncs*>(&GlibmmIOChannel::vfunc_table);
135
136   reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = this;
137 }
138
139 /* Construct an IOChannel wrapper for an already created GIOChannel.
140  * See the comment at the top of this file for an explanation of the
141  * problems with this approach.
142  */
143 IOChannel::IOChannel(GIOChannel* gobject, bool take_copy)
144 :
145   gobject_ (gobject)
146 {
147   // This ctor should never be called for GlibmmIOChannel instances.
148   g_assert(gobject != 0);
149   g_assert(gobject->funcs != &GlibmmIOChannel::vfunc_table);
150
151   if(take_copy)
152     g_io_channel_ref(gobject_);
153 }
154
155 IOChannel::~IOChannel()
156 {
157   if(gobject_)
158   {
159     // Check whether this IOChannel is implemented in C++, i.e. whether it
160     // uses our GlibmmIOChannel forwarding backend.  Normally, this will never
161     // be true because the wrapper should only be deleted in the io_free()
162     // callback, which clears gobject_ before deleting.  But in case the ctor
163     // of a derived class threw an exception the GIOChannel must be destroyed
164     // prematurely.
165     //
166     if(gobject_->funcs == &GlibmmIOChannel::vfunc_table)
167     {
168       // Disconnect the wrapper object so that it won't be deleted twice.
169       reinterpret_cast<GlibmmIOChannel*>(gobject_)->wrapper = 0;
170     }
171
172     GIOChannel *const tmp_gobject = gobject_;
173     gobject_ = 0;
174
175     g_io_channel_unref(tmp_gobject);
176   }
177 }
178
179 Glib::RefPtr<IOChannel> IOChannel::create_from_file(const std::string& filename, const std::string& mode)
180 {
181   GError* error = 0;
182   GIOChannel *const channel = g_io_channel_new_file(filename.c_str(), mode.c_str(), &error);
183
184   if(error)
185     Glib::Error::throw_exception(error);
186
187   return Glib::wrap(channel, false);
188 }
189
190 Glib::RefPtr<IOChannel> IOChannel::create_from_fd(int fd)
191 {
192   return Glib::wrap(g_io_channel_unix_new(fd), false);
193 }
194
195 #ifdef G_OS_WIN32
196
197 Glib::RefPtr<IOChannel> IOChannel::create_from_win32_fd(int fd)
198 {
199   return Glib::wrap(g_io_channel_win32_new_fd(fd), false);
200 }
201
202 Glib::RefPtr<IOChannel> IOChannel::create_from_win32_socket(int socket)
203 {
204   return Glib::wrap(g_io_channel_win32_new_socket(socket), false);
205 }
206
207 #endif /* G_OS_WIN32 */
208
209 IOStatus IOChannel::write(const Glib::ustring& str)
210 {
211   gsize bytes_written = 0;
212   return write(str.data(), str.bytes(), bytes_written);
213 }
214
215 IOStatus IOChannel::read_line(Glib::ustring& line)
216 {
217   Glib::ScopedPtr<char> buf;
218   GError* error = 0;
219   gsize   bytes = 0;
220
221   const GIOStatus status = g_io_channel_read_line(gobj(), buf.addr(), &bytes, 0, &error);
222
223   if(error)
224     Glib::Error::throw_exception(error);
225
226   if(buf.get())
227     line.assign(buf.get(), buf.get() + bytes);
228   else
229     line.erase();
230
231   return (IOStatus) status;
232 }
233
234 IOStatus IOChannel::read_to_end(Glib::ustring& str)
235 {
236   Glib::ScopedPtr<char> buf;
237   GError* error = 0;
238   gsize   bytes = 0;
239
240   const GIOStatus status = g_io_channel_read_to_end(gobj(), buf.addr(), &bytes, &error);
241
242   if(error)
243     Glib::Error::throw_exception(error);
244
245   if(buf.get())
246     str.assign(buf.get(), buf.get() + bytes);
247   else
248     str.erase();
249
250   return (IOStatus) status;
251 }
252
253 IOStatus IOChannel::read(Glib::ustring& str, gsize count)
254 {
255   Glib::ScopedPtr<char> buf (g_new(char, count));
256   GError* error = 0;
257   gsize   bytes = 0;
258
259   const GIOStatus status = g_io_channel_read_chars(gobj(), buf.get(), count, &bytes, &error);
260
261   if(error)
262     Glib::Error::throw_exception(error);
263
264   if(buf.get())
265     str.assign(buf.get(), buf.get() + bytes);
266   else
267     str.erase();
268
269   return (IOStatus) status;
270 }
271
272 IOStatus IOChannel::set_encoding(const std::string& encoding)
273 {
274   GError* error = 0;
275
276   const GIOStatus status = g_io_channel_set_encoding(
277       gobj(), (encoding.empty()) ? 0 : encoding.c_str(), &error);
278
279   if(error)
280     Glib::Error::throw_exception(error);
281
282   return (IOStatus) status;
283 }
284
285 std::string IOChannel::get_encoding() const
286 {
287   const char *const encoding = g_io_channel_get_encoding(gobject_);
288   return (encoding) ? std::string(encoding) : std::string();
289 }
290
291 void IOChannel::set_line_term(const std::string& term)
292 {
293   if(term.empty())
294     g_io_channel_set_line_term(gobj(), 0, 0);
295   else
296     g_io_channel_set_line_term(gobj(), term.data(), term.size());
297 }
298
299 std::string IOChannel::get_line_term() const
300 {
301   int len = 0;
302   const char *const term = g_io_channel_get_line_term(gobject_, &len);
303
304   return (term) ? std::string(term, len) : std::string();
305 }
306
307 Glib::RefPtr<IOSource> IOChannel::create_watch(IOCondition condition)
308 {
309   // The corresponding unreference() takes place in the dtor
310   // of the Glib::RefPtr<IOChannel> object below.
311   reference();
312   return IOSource::create(Glib::RefPtr<IOChannel>(this), condition);
313 }
314
315 IOStatus IOChannel::read_vfunc(char*, gsize, gsize&)
316 {
317   g_assert_not_reached();
318   return IO_STATUS_ERROR;
319 }
320
321 IOStatus IOChannel::write_vfunc(const char*, gsize, gsize&)
322 {
323   g_assert_not_reached();
324   return IO_STATUS_ERROR;
325 }
326
327 IOStatus IOChannel::seek_vfunc(gint64, SeekType)
328 {
329   g_assert_not_reached();
330   return IO_STATUS_ERROR;
331 }
332
333 IOStatus IOChannel::close_vfunc()
334 {
335   g_assert_not_reached();
336   return IO_STATUS_ERROR;
337 }
338
339 Glib::RefPtr<Glib::Source> IOChannel::create_watch_vfunc(IOCondition)
340 {
341   g_assert_not_reached();
342   return Glib::RefPtr<Glib::Source>();
343 }
344
345 IOStatus IOChannel::set_flags_vfunc(IOFlags)
346 {
347   g_assert_not_reached();
348   return IO_STATUS_ERROR;
349 }
350
351 IOFlags IOChannel::get_flags_vfunc()
352 {
353   g_assert_not_reached();
354   return IOFlags(0);
355 }
356
357 void IOChannel::reference() const
358 {
359   g_io_channel_ref(gobject_);
360 }
361
362 void IOChannel::unreference() const
363 {
364   g_io_channel_unref(gobject_);
365 }
366
367 Glib::RefPtr<IOChannel> wrap(GIOChannel* gobject, bool take_copy)
368 {
369   IOChannel* cpp_object = 0;
370
371   if(gobject)
372   {
373     if(gobject->funcs == &GlibmmIOChannel::vfunc_table)
374     {
375       cpp_object = reinterpret_cast<GlibmmIOChannel*>(gobject)->wrapper;
376
377       if(take_copy && cpp_object)
378         cpp_object->reference();
379     }
380     else
381     {
382       cpp_object = new ForeignIOChannel(gobject, take_copy);
383       cpp_object->reference(); // the refcount is initially 0
384     }
385   }
386
387   return Glib::RefPtr<IOChannel>(cpp_object);
388 }
389
390
391 /**** Glib::GlibmmIOChannel ************************************************/
392
393 // static
394 GIOStatus GlibmmIOChannel::io_read(GIOChannel* channel, char* buf, gsize count,
395                                    gsize* bytes_read, GError** err)
396 {
397   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
398
399   try
400   {
401     return (GIOStatus) wrapper->read_vfunc(buf, count, *bytes_read);
402   }
403   catch(Glib::Error& error)
404   {
405     error.propagate(err);
406   }
407   catch(...)
408   {
409     Glib::exception_handlers_invoke();
410   }
411
412   return G_IO_STATUS_ERROR;
413 }
414
415 // static
416 GIOStatus GlibmmIOChannel::io_write(GIOChannel* channel, const char* buf, gsize count,
417                                     gsize* bytes_written, GError** err)
418 {
419   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
420
421   try
422   {
423     return (GIOStatus) wrapper->write_vfunc(buf, count, *bytes_written);
424   }
425   catch(Glib::Error& error)
426   {
427     error.propagate(err);
428   }
429   catch(...)
430   {
431     Glib::exception_handlers_invoke();
432   }
433
434   return G_IO_STATUS_ERROR;
435 }
436
437 // static
438 GIOStatus GlibmmIOChannel::io_seek(GIOChannel* channel, gint64 offset, GSeekType type, GError** err)
439 {
440   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
441
442   try
443   {
444     return (GIOStatus) wrapper->seek_vfunc(offset, (SeekType) type);
445   }
446   catch(Glib::Error& error)
447   {
448     error.propagate(err);
449   }
450   catch(...)
451   {
452     Glib::exception_handlers_invoke();
453   }
454
455   return G_IO_STATUS_ERROR;
456 }
457
458 // static
459 GIOStatus GlibmmIOChannel::io_close(GIOChannel* channel, GError** err)
460 {
461   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
462
463   try
464   {
465     return (GIOStatus) wrapper->close_vfunc();
466   }
467   catch(Glib::Error& error)
468   {
469     error.propagate(err);
470   }
471   catch(...)
472   {
473     Glib::exception_handlers_invoke();
474   }
475
476   return G_IO_STATUS_ERROR;
477 }
478
479 // static
480 GSource* GlibmmIOChannel::io_create_watch(GIOChannel* channel, GIOCondition condition)
481 {
482   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
483
484   try
485   {
486     const Glib::RefPtr<Source> source = wrapper->create_watch_vfunc((IOCondition) condition);
487     return (source) ? source->gobj_copy() : 0;
488   }
489   catch(...)
490   {
491     Glib::exception_handlers_invoke();
492   }
493
494   return 0;
495 }
496
497 // static
498 void GlibmmIOChannel::io_free(GIOChannel* channel)
499 {
500   if(IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper)
501   {
502     wrapper->gobject_ = 0;
503     delete wrapper;
504   }
505
506   g_free(channel);
507 }
508
509 // static
510 GIOStatus GlibmmIOChannel::io_set_flags(GIOChannel* channel, GIOFlags flags, GError** err)
511 {
512   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
513
514   try
515   {
516     return (GIOStatus) wrapper->set_flags_vfunc((IOFlags) flags);
517   }
518   catch(Glib::Error& error)
519   {
520     error.propagate(err);
521   }
522   catch(...)
523   {
524     Glib::exception_handlers_invoke();
525   }
526
527   return G_IO_STATUS_ERROR;
528 }
529
530 // static
531 GIOFlags GlibmmIOChannel::io_get_flags(GIOChannel* channel)
532 {
533   IOChannel *const wrapper = reinterpret_cast<GlibmmIOChannel*>(channel)->wrapper;
534
535   try
536   {
537     return (GIOFlags) wrapper->get_flags_vfunc();
538   }
539   catch(...)
540   {
541     Glib::exception_handlers_invoke();
542   }
543
544   return GIOFlags(0);
545 }
546
547 } // namespace Glib
548
549
550 namespace
551 {
552 } // anonymous namespace
553
554
555 Glib::IOChannelError::IOChannelError(Glib::IOChannelError::Code error_code, const Glib::ustring& error_message)
556 :
557   Glib::Error (G_IO_CHANNEL_ERROR, error_code, error_message)
558 {}
559
560 Glib::IOChannelError::IOChannelError(GError* gobject)
561 :
562   Glib::Error (gobject)
563 {}
564
565 Glib::IOChannelError::Code Glib::IOChannelError::code() const
566 {
567   return static_cast<Code>(Glib::Error::code());
568 }
569
570 void Glib::IOChannelError::throw_func(GError* gobject)
571 {
572   throw Glib::IOChannelError(gobject);
573 }
574
575
576 namespace Glib
577 {
578
579
580 IOStatus IOChannel::read(gunichar& unichar)
581 {
582   GError *error = 0;
583   IOStatus retvalue = ((IOStatus)(g_io_channel_read_unichar(gobj(), &(unichar), &(error))));
584   if(error) ::Glib::Error::throw_exception(error);
585   return retvalue;
586 }
587
588 IOStatus IOChannel::read(char* buf, gsize count, gsize& bytes_read)
589 {
590   GError *error = 0;
591   IOStatus retvalue = ((IOStatus)(g_io_channel_read_chars(gobj(), buf, count, &(bytes_read), &(error))));
592   if(error) ::Glib::Error::throw_exception(error);
593   return retvalue;
594 }
595
596 IOStatus IOChannel::write(const char* buf, gssize count, gsize& bytes_written)
597 {
598   GError *error = 0;
599   IOStatus retvalue = ((IOStatus)(g_io_channel_write_chars(gobj(), buf, count, &(bytes_written), &(error))));
600   if(error) ::Glib::Error::throw_exception(error);
601   return retvalue;
602 }
603
604 IOStatus IOChannel::write(gunichar unichar)
605 {
606   GError *error = 0;
607   IOStatus retvalue = ((IOStatus)(g_io_channel_write_unichar(gobj(), unichar, &(error))));
608   if(error) ::Glib::Error::throw_exception(error);
609   return retvalue;
610 }
611
612 IOStatus IOChannel::seek(gint64 offset, SeekType type)
613 {
614   GError *error = 0;
615   IOStatus retvalue = ((IOStatus)(g_io_channel_seek_position(gobj(), offset, ((GSeekType)(type)), &(error))));
616   if(error) ::Glib::Error::throw_exception(error);
617   return retvalue;
618 }
619
620 IOStatus IOChannel::flush()
621 {
622   GError *error = 0;
623   IOStatus retvalue = ((IOStatus)(g_io_channel_flush(gobj(), &(error))));
624   if(error) ::Glib::Error::throw_exception(error);
625   return retvalue;
626 }
627
628 IOStatus IOChannel::close(bool flush)
629 {
630   GError *error = 0;
631   IOStatus retvalue = ((IOStatus)(g_io_channel_shutdown(gobj(), static_cast<int>(flush), &(error))));
632   if(error) ::Glib::Error::throw_exception(error);
633   return retvalue;
634 }
635
636 gsize IOChannel::get_buffer_size() const
637 {
638   return g_io_channel_get_buffer_size(const_cast<GIOChannel*>(gobj()));
639 }
640
641 void IOChannel::set_buffer_size(gsize size)
642 {
643   g_io_channel_set_buffer_size(gobj(), size);
644 }
645
646 IOFlags IOChannel::get_flags() const
647 {
648   return ((IOFlags)(g_io_channel_get_flags(const_cast<GIOChannel*>(gobj()))));
649 }
650
651 IOStatus IOChannel::set_flags(IOFlags flags)
652 {
653   GError *error = 0;
654   IOStatus retvalue = ((IOStatus)(g_io_channel_set_flags(gobj(), ((GIOFlags)(flags)), &(error))));
655   if(error) ::Glib::Error::throw_exception(error);
656   return retvalue;
657 }
658
659 void IOChannel::set_buffered(bool buffered)
660 {
661   g_io_channel_set_buffered(gobj(), static_cast<int>(buffered));
662 }
663
664 bool IOChannel::get_buffered() const
665 {
666   return g_io_channel_get_buffered(const_cast<GIOChannel*>(gobj()));
667 }
668
669 IOCondition IOChannel::get_buffer_condition() const
670 {
671   return ((IOCondition)(g_io_channel_get_buffer_condition(const_cast<GIOChannel*>(gobj()))));
672 }
673
674 bool IOChannel::get_close_on_unref() const
675 {
676   return g_io_channel_get_close_on_unref(const_cast<GIOChannel*>(gobj()));
677 }
678
679 void IOChannel::set_close_on_unref(bool do_close)
680 {
681   g_io_channel_set_close_on_unref(gobj(), static_cast<int>(do_close));
682 }
683
684
685 } // namespace Glib
686
687