Modified Files: glib/ChangeLog glib/glib/giochannel.h

Modified Files:
	glib/ChangeLog glib/glib/giochannel.h glib/glib/giochannel.c

	* glib/giochannel.h glib/giochannel.c: Added a length argument
	to g_io_channel_[set,get]_line_term(), allowing embeded nulls
	and binary safe line termination strings

	* glib/giochannel.c: Got rid of a compile warning in
	g_io_channel_write_chars()
This commit is contained in:
Ron Steinke 2001-09-10 23:59:33 +00:00
parent 7ca6b00d0e
commit d5485ef31b
10 changed files with 113 additions and 28 deletions

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -1,3 +1,12 @@
2001-09-10 Ron Steinke <rsteinke@w-link.net>
* glib/giochannel.h glib/giochannel.c: Added a length argument
to g_io_channel_[set,get]_line_term(), allowing embeded nulls
and binary safe line termination strings
* glib/giochannel.c: Got rid of a compile warning in
g_io_channel_write_chars()
Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org> Mon Sep 10 17:13:36 2001 Tim Janik <timj@gtk.org>
* glib/gmessages.h: got rid of g_set_error_handler(), * glib/gmessages.h: got rid of g_set_error_handler(),

View File

@ -76,6 +76,7 @@ g_io_channel_init (GIOChannel *channel)
channel->ref_count = 1; channel->ref_count = 1;
channel->encoding = g_strdup ("UTF-8"); channel->encoding = g_strdup ("UTF-8");
channel->line_term = NULL; channel->line_term = NULL;
channel->line_term_len = 0;
channel->buf_size = G_IO_NICE_BUF_SIZE; channel->buf_size = G_IO_NICE_BUF_SIZE;
channel->read_cd = (GIConv) -1; channel->read_cd = (GIConv) -1;
channel->write_cd = (GIConv) -1; channel->write_cd = (GIConv) -1;
@ -113,7 +114,8 @@ g_io_channel_unref (GIOChannel *channel)
g_iconv_close (channel->read_cd); g_iconv_close (channel->read_cd);
if (channel->write_cd != (GIConv) -1) if (channel->write_cd != (GIConv) -1)
g_iconv_close (channel->write_cd); g_iconv_close (channel->write_cd);
g_free (channel->line_term); if (channel->line_term)
g_free (channel->line_term);
if (channel->read_buf) if (channel->read_buf)
g_string_free (channel->read_buf, TRUE); g_string_free (channel->read_buf, TRUE);
if (channel->write_buf) if (channel->write_buf)
@ -625,29 +627,39 @@ g_io_channel_get_buffer_size (GIOChannel *channel)
* g_io_channel_set_line_term: * g_io_channel_set_line_term:
* @channel: a #GIOChannel * @channel: a #GIOChannel
* @line_term: The line termination string. Use %NULL for auto detect. * @line_term: The line termination string. Use %NULL for auto detect.
* Auto detection breaks on "\n", "\r\n", "\r", and * Auto detection breaks on "\n", "\r\n", "\r", "\0", and
* the unicode paragraph separator. Auto detection should * the unicode paragraph separator. Auto detection should
* not be used for anything other than file-based channels. * not be used for anything other than file-based channels.
* @length: The length of the termination string. If -1 is passed, the
* string is assumed to be null terminated. This option allows
* termination strings with embeded nulls.
* *
* This sets the string that #GIOChannel uses to determine * This sets the string that #GIOChannel uses to determine
* where in the file a line break occurs. * where in the file a line break occurs.
**/ **/
void void
g_io_channel_set_line_term (GIOChannel *channel, g_io_channel_set_line_term (GIOChannel *channel,
const gchar *line_term) const gchar *line_term,
gint length)
{ {
g_return_if_fail (channel != NULL); g_return_if_fail (channel != NULL);
g_return_if_fail (!line_term || line_term[0]); /* Disallow "" */ g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
g_return_if_fail (!line_term || g_utf8_validate (line_term, -1, NULL));
/* Require valid UTF-8 */
g_free (channel->line_term); if (line_term == NULL)
channel->line_term = g_strdup (line_term); length = 0;
else if (length < 0)
length = strlen (line_term);
if (channel->line_term)
g_free (channel->line_term);
channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
channel->line_term_len = length;
} }
/** /**
* g_io_channel_get_line_term: * g_io_channel_get_line_term:
* @channel: a #GIOChannel * @channel: a #GIOChannel
* @length: a location to return the length of the line terminator
* *
* This returns the string that #GIOChannel uses to determine * This returns the string that #GIOChannel uses to determine
* where in the file a line break occurs. A value of %NULL * where in the file a line break occurs. A value of %NULL
@ -657,10 +669,14 @@ g_io_channel_set_line_term (GIOChannel *channel,
* is owned by GLib and must not be freed. * is owned by GLib and must not be freed.
**/ **/
G_CONST_RETURN gchar* G_CONST_RETURN gchar*
g_io_channel_get_line_term (GIOChannel *channel) g_io_channel_get_line_term (GIOChannel *channel,
gint *length)
{ {
g_return_val_if_fail (channel != NULL, 0); g_return_val_if_fail (channel != NULL, 0);
if (length)
*length = channel->line_term_len;
return channel->line_term; return channel->line_term;
} }
@ -1440,7 +1456,7 @@ g_io_channel_read_line_backend (GIOChannel *channel,
status = G_IO_STATUS_NORMAL; status = G_IO_STATUS_NORMAL;
if (channel->line_term) if (channel->line_term)
line_term_len = strlen (channel->line_term); line_term_len = channel->line_term_len;
else else
line_term_len = 3; line_term_len = 3;
/* This value used for setting checked_to, it's the longest of the four /* This value used for setting checked_to, it's the longest of the four
@ -1500,14 +1516,14 @@ read_again:
first_time = FALSE; first_time = FALSE;
lastchar = use_buf->str + strlen (use_buf->str); lastchar = use_buf->str + use_buf->len;
for (nextchar = use_buf->str + checked_to; nextchar < lastchar; for (nextchar = use_buf->str + checked_to; nextchar < lastchar;
channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++) channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++)
{ {
if (channel->line_term) if (channel->line_term)
{ {
if (strncmp (channel->line_term, nextchar, line_term_len) == 0) if (memcmp (channel->line_term, nextchar, line_term_len) == 0)
{ {
line_length = nextchar - use_buf->str; line_length = nextchar - use_buf->str;
got_term_len = line_term_len; got_term_len = line_term_len;
@ -1540,22 +1556,18 @@ read_again:
goto done; goto done;
} }
break; break;
case '\0': /* Embeded null in input */
line_length = nextchar - use_buf->str;
got_term_len = 1;
goto done;
default: /* no match */ default: /* no match */
break; break;
} }
} }
} }
g_assert (nextchar == lastchar); /* Valid UTF-8, didn't overshoot */ /* If encoding != NULL, valid UTF-8, didn't overshoot */
g_assert (nextchar == lastchar);
/* Also terminate on '\0' */
line_length = lastchar - use_buf->str;
if (line_length < use_buf->len)
{
got_term_len = 0;
break;
}
/* Check for EOF */ /* Check for EOF */
@ -1572,10 +1584,7 @@ read_again:
break; break;
} }
if (use_buf->len > line_term_len - 1) checked_to = MAX (use_buf->len - (line_term_len - 1), 0);
checked_to = use_buf->len - (line_term_len - 1);
else
checked_to = 0;
} }
done: done:
@ -2041,6 +2050,7 @@ reconvert:
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
err = (size_t) -1;
errnum = 0; /* Don't confunse the compiler */ errnum = 0; /* Don't confunse the compiler */
} }
} }

View File

@ -111,6 +111,7 @@ struct _GIOChannel
GIConv read_cd; GIConv read_cd;
GIConv write_cd; GIConv write_cd;
gchar *line_term; /* String which indicates the end of a line of text */ gchar *line_term; /* String which indicates the end of a line of text */
guint line_term_len; /* So we can have null in the line term */
gsize buf_size; gsize buf_size;
GString *read_buf; /* Raw data from the channel */ GString *read_buf; /* Raw data from the channel */
@ -205,8 +206,10 @@ GIOStatus g_io_channel_set_flags (GIOChannel *channel,
GError **error); GError **error);
GIOFlags g_io_channel_get_flags (GIOChannel *channel); GIOFlags g_io_channel_get_flags (GIOChannel *channel);
void g_io_channel_set_line_term (GIOChannel *channel, void g_io_channel_set_line_term (GIOChannel *channel,
const gchar *line_term); const gchar *line_term,
G_CONST_RETURN gchar* g_io_channel_get_line_term (GIOChannel *channel); gint length);
G_CONST_RETURN gchar* g_io_channel_get_line_term (GIOChannel *channel,
gint *length);
void g_io_channel_set_buffered (GIOChannel *channel, void g_io_channel_set_buffered (GIOChannel *channel,
gboolean buffered); gboolean buffered);
gboolean g_io_channel_get_buffered (GIOChannel *channel); gboolean g_io_channel_get_buffered (GIOChannel *channel);