common: Fix warning for portability.
[gnupg.git] / common / t-iobuf.c
index 0f21c35..bdeab99 100644 (file)
@@ -5,7 +5,10 @@
 #include <stdlib.h>
 
 #include "iobuf.h"
+#include "stringhelp.h"
 
+/* Return every other byte.  In particular, reads two bytes, returns
+   the second one.  */
 static int
 every_other_filter (void *opaque, int control,
                    iobuf_t chain, byte *buf, size_t *len)
@@ -14,7 +17,7 @@ every_other_filter (void *opaque, int control,
 
   if (control == IOBUFCTRL_DESC)
     {
-      *(char **) buf = "every_other_filter";
+      mem2str (buf, "every_other_filter", *len);
     }
   if (control == IOBUFCTRL_UNDERFLOW)
     {
@@ -25,7 +28,7 @@ every_other_filter (void *opaque, int control,
       else
        c2 = iobuf_readbyte (chain);
 
-      // printf ("Discarding %d (%c); return %d (%c)\n", c, c, c2, c2);
+      /* printf ("Discarding %d (%c); return %d (%c)\n", c, c, c2, c2); */
 
       if (c2 == -1)
        {
@@ -42,6 +45,36 @@ every_other_filter (void *opaque, int control,
   return 0;
 }
 
+static int
+double_filter (void *opaque, int control,
+              iobuf_t chain, byte *buf, size_t *len)
+{
+  (void) opaque;
+
+  if (control == IOBUFCTRL_DESC)
+    {
+      mem2str (buf, "double_filter", *len);
+    }
+  if (control == IOBUFCTRL_FLUSH)
+    {
+      int i;
+
+      for (i = 0; i < *len; i ++)
+       {
+         int rc;
+
+         rc = iobuf_writebyte (chain, buf[i]);
+         if (rc)
+           return rc;
+         rc = iobuf_writebyte (chain, buf[i]);
+         if (rc)
+           return rc;
+       }
+    }
+
+  return 0;
+}
+
 struct content_filter_state
 {
   int pos;
@@ -79,15 +112,14 @@ content_filter (void *opaque, int control,
       if (toread > remaining)
        toread = remaining;
 
-      if (toread == 0)
-       return -1;
-
       memcpy (buf, &state->buffer[state->pos], toread);
 
       state->pos += toread;
 
       *len = toread;
 
+      if (toread == 0)
+       return -1;
       return 0;
     }
 
@@ -117,12 +149,12 @@ main (int argc, char *argv[])
     n = 0;
     while ((c = iobuf_readbyte (iobuf)) != -1)
       {
-       // printf ("%d: %c\n", n + 1, (char) c);
+       /* printf ("%d: %c\n", n + 1, (char) c); */
        assert (content[2 * n + 1] == c);
        n ++;
       }
-    // printf ("Got EOF after reading %d bytes (content: %d)\n",
-    // n, strlen (content));
+    /* printf ("Got EOF after reading %d bytes (content: %d)\n", */
+    /*         n, strlen (content)); */
     assert (n == strlen (content) / 2);
 
     iobuf_close (iobuf);
@@ -153,11 +185,13 @@ main (int argc, char *argv[])
 
     while ((c = iobuf_readbyte (iobuf)) != -1)
       {
-       // printf ("%d: %c\n", n + 1, (char) c);
+       /* printf ("%d: %c\n", n + 1, (char) c); */
        assert (content[2 * (n - 5) + 1] == c);
        n ++;
       }
     assert (n == 10 + (strlen (content) - 10) / 2);
+
+    iobuf_close (iobuf);
   }
 
 
@@ -234,13 +268,13 @@ main (int argc, char *argv[])
     /* The string should have been truncated (max_len == 0).  */
     assert (max_len == 0);
     free (buffer);
+
+    iobuf_close (iobuf);
   }
 
   {
-    /* - 3 characters plus new line
-       - 4 characters plus new line
-       - 5 characters plus new line
-       - 5 characters, no new line
+    /* - 10 characters, EOF
+       - 17 characters, EOF
      */
     char *content = "abcdefghijklmnopq";
     char *content2 = "0123456789";
@@ -249,10 +283,12 @@ main (int argc, char *argv[])
     int c;
     int n;
     int lastc = 0;
+    struct content_filter_state *state;
 
     iobuf = iobuf_temp_with_content (content, strlen(content));
     rc = iobuf_push_filter (iobuf,
-                           content_filter, content_filter_new (content2));
+                           content_filter,
+                            state=content_filter_new (content2));
     assert (rc == 0);
 
     n = 0;
@@ -261,20 +297,97 @@ main (int argc, char *argv[])
        c = iobuf_readbyte (iobuf);
        if (c == -1 && lastc == -1)
          {
-           printf("Two EOFs in a row.  Done.\n");
+           /* printf("Two EOFs in a row.  Done.\n");  */
+           assert (n == 27);
            break;
          }
 
        lastc = c;
 
        if (c == -1)
-         printf("After %d bytes, got EOF.\n", n);
+         {
+           /* printf("After %d bytes, got EOF.\n", n); */
+           assert (n == 10 || n == 27);
+         }
        else
          {
            n ++;
-           printf ("%d: '%c' (%d)\n", n, c, c);
+           /* printf ("%d: '%c' (%d)\n", n, c, c); */
          }
       }
+
+    iobuf_close (iobuf);
+    free (state);
+  }
+
+  /* Write some data to a temporary filter.  Push a new filter.  The
+     already written data should not be processed by the new
+     filter.  */
+  {
+    iobuf_t iobuf;
+    int rc;
+    char *content = "0123456789";
+    char *content2 = "abc";
+    char buffer[4096];
+    int n;
+
+    iobuf = iobuf_temp ();
+    assert (iobuf);
+
+    rc = iobuf_write (iobuf, content, strlen (content));
+    assert (rc == 0);
+
+    rc = iobuf_push_filter (iobuf, double_filter, NULL);
+    assert (rc == 0);
+
+    /* Include a NUL.  */
+    rc = iobuf_write (iobuf, content2, strlen (content2) + 1);
+    assert (rc == 0);
+
+    n = iobuf_temp_to_buffer (iobuf, buffer, sizeof (buffer));
+#if 0
+    printf ("Got %d bytes\n", n);
+    printf ("buffer: `");
+    fwrite (buffer, n, 1, stdout);
+    fputc ('\'', stdout);
+    fputc ('\n', stdout);
+#endif
+
+    assert (n == strlen (content) + 2 * (strlen (content2) + 1));
+    assert (strcmp (buffer, "0123456789aabbcc") == 0);
+
+    iobuf_close (iobuf);
+  }
+
+  {
+    iobuf_t iobuf;
+    int rc;
+    char content[] = "0123456789";
+    int n;
+    int c;
+    char buffer[10];
+
+    assert (sizeof buffer == sizeof content - 1);
+
+    iobuf = iobuf_temp_with_content (content, strlen (content));
+    assert (iobuf);
+
+    rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
+    assert (rc == 0);
+    rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
+    assert (rc == 0);
+
+    for (n = 0; (c = iobuf_get (iobuf)) != -1; n ++)
+      {
+       /* printf ("%d: `%c'\n", n, c);  */
+       buffer[n] = c;
+      }
+
+    assert (n == 2);
+    assert (buffer[0] == '3');
+    assert (buffer[1] == '7');
+
+    iobuf_close (iobuf);
   }
 
   return 0;