GNOME Bugzilla – Bug 572471
Giomm streams cannot be inherited from (add vfuncs at ABI break)
Last modified: 2016-11-21 15:32:41 UTC
It's impossible to define new types of streams in giomm. Firstly, it's impossible to inherit from InputStream and FilterInputStream, and secondly even if I inherit from a constructible type, the stream is not polymorphic (i.e. it simply doesn't work in the situations that matter). This could be solved by giving Gio::InputStream an Gio::OutputStream a couple of vfuncs that correspond to the virtual methods of GInputStream and GOutputStream GObjects, in a matter similar to e.g. Gtk::CellRenderer.
Yes, we chose not to wrap the vfuncs (via _WRAP_VFUNC()) in giomm, because we thought that almost nobody would want to do this and we were worried about the bugs it could introduce in the short term. But if you have a real-world test case, and a real use for them, we could add these in a future ABI break. That's likely to happen in the nearish future, if the glib/gtk+ 3.0 ABI break really happens. So a patch would be welcome.
A real-world use case would be a base64-encoded stream, or streams that write compressed files. This way if I have a function in an image processing app like this: void Document::save_png_image(Glib::RefPtr<Gio::OutputStream>) and I want to create an SVG document which embeds this PNG as a base64-encoded data: URI, I can pass it a Base64OutputStream, which is derived from Gio::FilterOutputStream and writes the base64-encoded data directly into the output file. I could do this in a roundabout way by base64-encoding data written to a MemoryOutputStream, but then I would need to save the entire file into memory, increasing the memory footprint of my application.
Could you please try to add the vfuncs in the gtkmm3-maybe branch, along with a test/example to show that the idea works.
OK, working on a patch, though I'm not very familiar with the gtkmm binding tools and it might take a while.
I noticed that there is no 3.0 branch for glibmm yet. Should I work from glibmm master instead?
Sorry, yes, just use master for now please. We'll branch when we have something to commit there.
Created attachment 150564 [details] [review] Wrap stream vfuncs Initial version of a patch to allow creating custom streams. I had to create hand-coded wrappers, because the vfuncs are different if exceptions are disabled. For now only synchronous operations are wrapped. The patch includes a new test, which defines a filter output stream class that base64 encodes the data that passes through it. I had to fix a bug with MemoryOutputStream that made it completely unusable: GMemoryOutputStream does not use construction properties, so we cannot use the vanilla constructor wrapper. I added a workaround that just calls g_memory_output_stream_new. I will report this as a separate issue, because it doesn't break ABI to fix this.
MemoryOutputStream issue reported here: https://bugzilla.gnome.org/show_bug.cgi?id=605710
*** Bug 642111 has been marked as a duplicate of this bug. ***
Note that the patch can now be simplified because we no longer use the no-exceptions ifdefs.
I have updated Krzysztof's patch and split it into several smaller patches. I have also pushed those parts that don't break ABI. New vfuncs and the new test case must wait until we can break ABI. Gio::FilterOutputStream::property_base_stream() was declared with the wrong return type. I have pushed Krzysztof's fix. Was Glib::PropertyProxy_ReadOnly< Glib::RefPtr<InputStream> > Is Glib::PropertyProxy_ReadOnly< Glib::RefPtr<OutputStream> > This fix breaks API, but it does not break ABI. The return type is not part of the mangled name, and only the type of a pointer differs. I guess that the property with the wrong return type has been useless. The API break should be acceptable. Unfortunately gmmproc does not detect such an error. In the .defs file, the type is specified as GParamObject, which can be any kind of GObject.
Created attachment 328926 [details] [review] patch: Wrap some vfuncs in giomm streams This patch adds vfuncs in BufferedInputStream, InputStream and OutputStream. No vfunc is hand-coded now.
Created attachment 328927 [details] [review] patch: Add tests/giomm_stream_vfuncs This is an updated version of Krzysztof's test case. It requires the vfuncs.
The remaining two pathces have been pushed to the git master branch. They will be included in the ABI-breaking glibmm 2.52 release.