digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
[gnulib.git] / tests / test-pipe-filter-ii1.c
1 /* Test of filtering of data through a subprocess.
2    Copyright (C) 2009 Free Software Foundation, Inc.
3    Written by Bruno Haible <haible@clisp.cons.org>, 2009.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include "pipe-filter.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "binary-io.h"
26 #include "c-ctype.h"
27 #include "read-file.h"
28 #include "progname.h"
29
30 #define ASSERT(expr) \
31   do                                                                         \
32     {                                                                        \
33       if (!(expr))                                                           \
34         {                                                                    \
35           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
36           fflush (stderr);                                                   \
37           abort ();                                                          \
38         }                                                                    \
39     }                                                                        \
40   while (0)
41
42
43 /* Pipe a text file through 'tr a-z A-Z', which converts ASCII characters from
44    lower case to upper case.  */
45
46 struct locals
47 {
48   const char *input;
49   size_t size;
50   size_t nwritten;
51   size_t nread;
52   char buf[19];
53 };
54
55 static const void *
56 prepare_write (size_t *num_bytes_p, void *private_data)
57 {
58   struct locals *l = (struct locals *) private_data;
59   if (l->nwritten < l->size)
60     {
61       *num_bytes_p = l->size - l->nwritten;
62       return l->input + l->nwritten;
63     }
64   else
65     return NULL;
66 }
67
68 static void
69 done_write (void *data_written, size_t num_bytes_written, void *private_data)
70 {
71   struct locals *l = (struct locals *) private_data;
72   l->nwritten += num_bytes_written;
73 }
74
75 static void *
76 prepare_read (size_t *num_bytes_p, void *private_data)
77 {
78   struct locals *l = (struct locals *) private_data;
79   *num_bytes_p = sizeof (l->buf);
80   return l->buf;
81 }
82
83 static void
84 done_read (void *data_read, size_t num_bytes_read, void *private_data)
85 {
86   struct locals *l = (struct locals *) private_data;
87   const char *p = l->input + l->nread;
88   const char *q = (const char *) data_read;
89   size_t i;
90
91   for (i = 0; i < num_bytes_read; i++, q++)
92     {
93       /* Handle conversion NL -> CRLF possibly done by the child process.  */
94       if (!(O_BINARY && *q == '\r'))
95         {
96           char orig = *p;
97           char expected = c_toupper (orig);
98           ASSERT (*q == expected);
99           p++;
100         }
101     }
102   l->nread = p - l->input;
103 }
104
105 int
106 main (int argc, char *argv[])
107 {
108   const char *tr_program;
109   const char *input_filename;
110   size_t input_size;
111   char *input;
112
113   set_program_name (argv[0]);
114
115   ASSERT (argc == 3);
116
117   tr_program = argv[1];
118
119   /* Read some text from a file.  */
120   input_filename = argv[2];
121   input = read_binary_file (input_filename, &input_size);
122   ASSERT (input != NULL);
123
124   /* Convert it to uppercase, line by line.  */
125   {
126     const char *argv[4];
127     struct locals l;
128     int result;
129
130     l.input = input;
131     l.size = input_size;
132     l.nwritten = 0;
133     l.nread = 0;
134
135     argv[0] = tr_program;
136     argv[1] = "a-z";
137     argv[2] = "A-Z";
138     argv[3] = NULL;
139
140     result = pipe_filter_ii_execute ("tr", tr_program, argv, false, true,
141                                      prepare_write, done_write,
142                                      prepare_read, done_read,
143                                      &l);
144     ASSERT (result == 0);
145     ASSERT (l.nwritten == input_size);
146     ASSERT (l.nread == input_size);
147   }
148
149   return 0;
150 }