From ec759772de74f80137182f15c2a74c0b0d027729 Mon Sep 17 00:00:00 2001 From: Ron Steinke Date: Sun, 5 Aug 2001 20:26:09 +0000 Subject: [PATCH] Modified Files: glib/ChangeLog glib/glib/giochannel.h Modified Files: glib/ChangeLog glib/glib/giochannel.h glib/glib/giochannel.c glib/glib/glib.def glib/docs/reference/glib/glib-sections.txt * glib/giochannel.c glib/giochannel.c glib/glib.def docs/reference/glib/glib-sections.txt: Added new functions g_io_channel_[read,write]_unichar () * glib/giochannel.h: Finally remembered to remove the old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () and g_io_channel_write_chars () --- ChangeLog | 12 +++ ChangeLog.pre-2-0 | 12 +++ ChangeLog.pre-2-10 | 12 +++ ChangeLog.pre-2-12 | 12 +++ ChangeLog.pre-2-2 | 12 +++ ChangeLog.pre-2-4 | 12 +++ ChangeLog.pre-2-6 | 12 +++ ChangeLog.pre-2-8 | 12 +++ docs/reference/glib/glib-sections.txt | 2 + glib/giochannel.c | 120 ++++++++++++++++++++++++-- glib/giochannel.h | 8 +- glib/glib.def | 2 + 12 files changed, 217 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9810b9307..81fa4dcce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 9810b9307..81fa4dcce 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,15 @@ +2001-08-05 Ron Steinke + + * glib/giochannel.c glib/giochannel.c glib/glib.def + docs/reference/glib/glib-sections.txt: Added new functions + g_io_channel_[read,write]_unichar () + + * glib/giochannel.h: Finally remembered to remove the + old error message G_IO_CHANNEL_ERROR_PCHAR_FLUSH + + * glib/giochannel.c: Some fixes to g_io_channel_fill_buffer () + and g_io_channel_write_chars () + 2001-08-05 Ron Steinke * glib/giochannel.c: Replaced the local use_buf variable with a macro diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 956fccbe0..28f75b211 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -595,10 +595,12 @@ g_io_channel_init g_io_channel_new_file g_io_channel_read_chars +g_io_channel_read_unichar g_io_channel_read_line g_io_channel_read_line_string g_io_channel_read_to_end g_io_channel_write_chars +g_io_channel_write_unichar g_io_channel_flush g_io_channel_seek_position GSeekType diff --git a/glib/giochannel.c b/glib/giochannel.c index 4c40bbde8..545ef24fc 100644 --- a/glib/giochannel.c +++ b/glib/giochannel.c @@ -1132,17 +1132,16 @@ g_io_channel_fill_buffer (GIOChannel *channel, reencode: inbytes_left = channel->read_buf->len; - outbytes_left = MIN (channel->buf_size / 4, + outbytes_left = MAX (6, MAX (channel->read_buf->len, channel->encoded_read_buf->allocated_len - - channel->encoded_read_buf->len); + - channel->encoded_read_buf->len)); + + inbuf = channel->read_buf->str; + outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len; g_string_set_size (channel->encoded_read_buf, channel->encoded_read_buf->len + outbytes_left); - inbuf = channel->read_buf->str; - outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len - - outbytes_left; - errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left, &outbuf, &outbytes_left); @@ -1163,6 +1162,8 @@ reencode: status = G_IO_STATUS_NORMAL; break; case E2BIG: + /* Buffer size at least 6, wrote at least on character */ + g_assert (inbuf != channel->read_buf->str); goto reencode; case EILSEQ: if (oldlen < channel->encoded_read_buf->len) @@ -1694,6 +1695,66 @@ g_io_channel_read_chars (GIOChannel *channel, return G_IO_STATUS_NORMAL; } +/** + * g_io_channel_read_unichar: + * @channel: a #GIOChannel + * @thechar: a location to return a character + * @error: A location to return an error of type #GConvertError + * or #GIOChannelError + * + * This function cannot be called on a channel with %NULL encoding. + * + * Return value: a #GIOStatus + **/ +GIOStatus +g_io_channel_read_unichar (GIOChannel *channel, + gunichar *thechar, + GError **error) +{ + GIOStatus status = G_IO_STATUS_NORMAL; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); + + while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL) + status = g_io_channel_fill_buffer (channel, error); + + /* Only return an error if we have no data */ + + if (BUF_LEN (USE_BUF (channel)) == 0) + { + g_assert (status != G_IO_STATUS_NORMAL); + + if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0) + { + g_set_error (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_PARTIAL_INPUT, + "Leftover unconverted data in read buffer"); + status = G_IO_STATUS_ERROR; + } + + if (thechar) + *thechar = (gunichar) -1; + + return status; + } + + if (status == G_IO_STATUS_ERROR) + g_clear_error (error); + + if (thechar) + *thechar = g_utf8_get_char (channel->encoded_read_buf->str); + + g_string_erase (channel->encoded_read_buf, 0, + g_utf8_next_char (channel->encoded_read_buf->str) + - channel->encoded_read_buf->str); + + return G_IO_STATUS_NORMAL; +} + /** * g_io_channel_write_chars: * @channel: a #GIOChannel @@ -1720,7 +1781,6 @@ g_io_channel_write_chars (GIOChannel *channel, gssize wrote_bytes = 0; g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); - g_return_val_if_fail (bytes_written != NULL, G_IO_STATUS_ERROR); g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); @@ -1783,8 +1843,7 @@ g_io_channel_write_chars (GIOChannel *channel, did_write += this_time; } while (status == G_IO_STATUS_NORMAL && - did_write < MIN (channel->write_buf->len, - MAX (MAX_CHAR_SIZE, channel->buf_size / 4))); + did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE)); g_string_erase (channel->write_buf, 0, did_write); @@ -1993,6 +2052,49 @@ reconvert: return G_IO_STATUS_NORMAL; } +/** + * g_io_channel_write_unichar: + * @channel: a #GIOChannel + * @thechar: a character + * @error: A location to return an error of type #GConvertError + * or #GIOChannelError + * + * This function cannot be called on a channel with %NULL encoding. + * + * Return value: a #GIOStatus + **/ +GIOStatus +g_io_channel_write_unichar (GIOChannel *channel, + gunichar thechar, + GError **error) +{ + GIOStatus status; + gchar static_buf[6]; + gsize char_len, wrote_len; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); + + char_len = g_unichar_to_utf8 (thechar, static_buf); + + if (channel->partial_write_buf[0] != '\0') + { + g_warning ("Partial charater written before writing unichar.\n"); + channel->partial_write_buf[0] = '\0'; + } + + status = g_io_channel_write_chars (channel, static_buf, + char_len, &wrote_len, error); + + /* We validate UTF-8, so we can't get a partial write */ + + g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL); + + return status; +} /** * g_io_channel_error_quark: diff --git a/glib/giochannel.h b/glib/giochannel.h index 2c31ee8e6..7fed662cc 100644 --- a/glib/giochannel.h +++ b/glib/giochannel.h @@ -61,8 +61,6 @@ typedef enum G_IO_CHANNEL_ERROR_OVERFLOW, G_IO_CHANNEL_ERROR_PIPE, /* Other */ - G_IO_CHANNEL_ERROR_PCHAR_FLUSH, - /* Unconverted partial UTF-8 chars in buffer during flush */ G_IO_CHANNEL_ERROR_FAILED } GIOChannelError; @@ -252,11 +250,17 @@ GIOStatus g_io_channel_read_chars (GIOChannel *channel, gsize count, gsize *bytes_read, GError **error); +GIOStatus g_io_channel_read_unichar (GIOChannel *channel, + gunichar *thechar, + GError **error); GIOStatus g_io_channel_write_chars (GIOChannel *channel, const gchar *buf, gssize count, gsize *bytes_written, GError **error); +GIOStatus g_io_channel_write_unichar (GIOChannel *channel, + gunichar thechar, + GError **error); GIOStatus g_io_channel_seek_position (GIOChannel *channel, glong offset, GSeekType type, diff --git a/glib/glib.def b/glib/glib.def index f3d8c8fdf..1e5487d13 100644 --- a/glib/glib.def +++ b/glib/glib.def @@ -204,6 +204,7 @@ EXPORTS g_io_channel_read_line g_io_channel_read_line_string g_io_channel_read_to_end + g_io_channel_read_unichar g_io_channel_ref g_io_channel_seek g_io_channel_seek_position @@ -225,6 +226,7 @@ EXPORTS g_io_channel_win32_set_debug g_io_channel_write g_io_channel_write_chars + g_io_channel_write_unichar g_io_create_watch g_list_alloc g_list_append