Re: GIOChannel missing binary mode?



> From: Michael Natterer <mitch gimp org>
>
> Ron Steinke <rsteinke w-link net> writes:
>
> > > From: Michael Natterer <mitch gimp org>
> > >
> > > Hi,
> > >
> > > while porting GIMP <-> plug-in communication to
> > > g_io_channel_[read|write]_chars() i noticed that there
> > > are two GIOChannel attributes, "do_encode" and "encoding".
> > >
> > > My impression from looking at the code is that if
> > > "do_encode" == FALSE, "encoding" is assumed to be UTF-8.
> > 
> > Actually, it's assumed to be either "UTF-8" or NULL. Use
> > NULL for binary encoding. The default just happens to
> > be "UTF-8".
> > 
> > > So either I missed something or there seems to be no way
> > > to use a GIOChannel in binary mode, because if I say
> > > g_io_channel_set_encoding (channel, NULL, NULL),
> > > "do_encoding" is set to FALSE automatically.
> > 
> > The do_encode flag is set when we are calling g_iconv to do conversion.
> > It just happens this is true for neither UTF-8 or binary encoding.
> > 
> > > A subsequent call to read_chars() or write_chars() however
> > > looks at "do_encode", assumes UTF-8 if it is FALSE and
> > > calls g_utf8_validate() which of course fails on binary
> > > data.
> > 
> > In write_chars(), a binary encoding hits the earlier !channel->encoding
> > test and completely avoids checking do_encode. In read_chars(),
> > the test for binary encoding is hidden in the USE_BUF() macro.
> > 
> > 
> > > Please point me to the right direction if I made a mistake :-)
> > >
> > > (FYI: right now, as a workaround, i use channel->funcs->io_foo())
> > 
> > Just call g_io_channel_set_encoding() with a NULL argument before
> > you use the channel. If this isn't in the docs, it should be.
>
> You're right, it was not g_io_channel_set_encoding()'s fault.
>
> In fact, I used g_io_channel_set_encoding() and it didn't work, so my
> first (and wrong) glance at giochannel.c made me think I found the bug.
>
> However I additionally have to say g_io_channel_set_buffered (channel, FALSE);
> to make it work.
>
> I tried to write a small test program to trigger the failing reads and
> writes (attached) but was *not* able to reproduce it, no matter if
> reading/writing is done on a tty, file of pipe. Resizing the random_crap
> array in the test program also doesn't trigger anything.
>
> Maybe GIMP's IO channel events are a bit more complex and trigger
> something completely different :-)  If you want to test it, remove
> the g_io_channel_set_buffered() from CVS gimp in app/plug_in.c and
> libgimp/gimp.c and see what happens.
>
> (Maybe it's just an explicit flush() or something that's missing
> to make it work in buffered mode...).

If the gimp has it's own read and write functions for the channel, this
could be causing the problem. The gimp functions would (I'm guessing)
use the old glib API functions, which know nothing about the buffers.
If you want to mix the new glib API functions with the old API functions,
you have to set the channel unbuffered. Otherwise, the old API functions
will read the next data from the disk instead of from the buffer (with
a similar problem with write).

If this isn't the case, could you be more explicit by what you mean by "failing"?
Do you mean "glib issues a warning" or "the iochannel functions return an error
when they shouldn't (e.g. a conversion error for NULL encoding)" or
"the data I read/write turns out to be garbage"?

Ron Steinke




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]