Modified Files: glib/ChangeLog glib/glib/giochannel.h
authorRon Steinke <rsteinke@src.gnome.org>
Mon, 10 Sep 2001 23:59:33 +0000 (23:59 +0000)
committerRon Steinke <rsteinke@src.gnome.org>
Mon, 10 Sep 2001 23:59:33 +0000 (23:59 +0000)
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()

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib/giochannel.c
glib/giochannel.h

index f63874a..7f3e328 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index f63874a..7f3e328 100644 (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>
 
        * glib/gmessages.h: got rid of g_set_error_handler(),
index 890cb1d..80bc797 100644 (file)
@@ -76,6 +76,7 @@ g_io_channel_init (GIOChannel *channel)
   channel->ref_count = 1;
   channel->encoding = g_strdup ("UTF-8");
   channel->line_term = NULL;
+  channel->line_term_len = 0;
   channel->buf_size = G_IO_NICE_BUF_SIZE;
   channel->read_cd = (GIConv) -1;
   channel->write_cd = (GIConv) -1;
@@ -113,7 +114,8 @@ g_io_channel_unref (GIOChannel *channel)
         g_iconv_close (channel->read_cd);
       if (channel->write_cd != (GIConv) -1)
         g_iconv_close (channel->write_cd);
-      g_free (channel->line_term);
+      if (channel->line_term)
+        g_free (channel->line_term);
       if (channel->read_buf)
         g_string_free (channel->read_buf, TRUE);
       if (channel->write_buf)
@@ -625,29 +627,39 @@ g_io_channel_get_buffer_size (GIOChannel  *channel)
  * g_io_channel_set_line_term:
  * @channel: a #GIOChannel
  * @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
  *             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
  * where in the file a line break occurs.
  **/
 void
 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 (!line_term || line_term[0]); /* Disallow "" */
-  g_return_if_fail (!line_term || g_utf8_validate (line_term, -1, NULL));
-                   /* Require valid UTF-8 */
+  g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
 
-  g_free (channel->line_term);
-  channel->line_term = g_strdup (line_term);
+  if (line_term == NULL)
+    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:
  * @channel: a #GIOChannel
+ * @length: a location to return the length of the line terminator
  *
  * This returns the string that #GIOChannel uses to determine
  * 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.
  **/
 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);
 
+  if (length)
+    *length = channel->line_term_len;
+
   return channel->line_term;
 }
 
@@ -1440,7 +1456,7 @@ g_io_channel_read_line_backend    (GIOChannel *channel,
   status = G_IO_STATUS_NORMAL;
 
   if (channel->line_term)
-    line_term_len = strlen (channel->line_term);
+    line_term_len = channel->line_term_len;
   else
     line_term_len = 3;
     /* This value used for setting checked_to, it's the longest of the four
@@ -1500,14 +1516,14 @@ read_again:
 
       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;
            channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++)
         {
           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;
                   got_term_len = line_term_len;
@@ -1540,22 +1556,18 @@ read_again:
                         goto done;
                       }
                     break;
+                  case '\0': /* Embeded null in input */
+                    line_length = nextchar - use_buf->str;
+                    got_term_len = 1;
+                    goto done;
                   default: /* no match */
                     break;
                 }
             }
         }
 
-      g_assert (nextchar == lastchar); /* Valid UTF-8, didn't overshoot */
-
-      /* Also terminate on '\0' */
-
-      line_length = lastchar - use_buf->str;
-      if (line_length < use_buf->len)
-        {
-          got_term_len = 0;
-          break;
-        }
+      /* If encoding != NULL, valid UTF-8, didn't overshoot */
+      g_assert (nextchar == lastchar);
 
       /* Check for EOF */
 
@@ -1572,10 +1584,7 @@ read_again:
           break;
         }
 
-      if (use_buf->len > line_term_len - 1)
-       checked_to = use_buf->len - (line_term_len - 1);
-      else
-       checked_to = 0;
+      checked_to = MAX (use_buf->len - (line_term_len - 1), 0);
     }
 
 done:
@@ -2041,6 +2050,7 @@ reconvert:
                         break;
                       default:
                         g_assert_not_reached ();
+                        err = (size_t) -1;
                         errnum = 0; /* Don't confunse the compiler */
                     }
                 }
index 89b327d..1ff325b 100644 (file)
@@ -111,6 +111,7 @@ struct _GIOChannel
   GIConv read_cd;
   GIConv write_cd;
   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;
   GString *read_buf;           /* Raw data from the channel */
@@ -205,8 +206,10 @@ GIOStatus             g_io_channel_set_flags            (GIOChannel   *channel,
                                                         GError      **error);
 GIOFlags              g_io_channel_get_flags            (GIOChannel   *channel);
 void                  g_io_channel_set_line_term        (GIOChannel   *channel,
-                                                        const gchar  *line_term);
-G_CONST_RETURN gchar* g_io_channel_get_line_term        (GIOChannel   *channel);
+                                                        const gchar  *line_term,
+                                                        gint          length);
+G_CONST_RETURN gchar* g_io_channel_get_line_term        (GIOChannel   *channel,
+                                                        gint         *length);
 void                 g_io_channel_set_buffered         (GIOChannel   *channel,
                                                         gboolean      buffered);
 gboolean             g_io_channel_get_buffered         (GIOChannel   *channel);