8 #include "stringhelp.h"
10 /* Return every other byte. In particular, reads two bytes, returns
13 every_other_filter (void *opaque, int control,
14 iobuf_t chain, byte *buf, size_t *len)
18 if (control == IOBUFCTRL_DESC)
20 mem2str (buf, "every_other_filter", *len);
22 if (control == IOBUFCTRL_UNDERFLOW)
24 int c = iobuf_readbyte (chain);
29 c2 = iobuf_readbyte (chain);
31 /* printf ("Discarding %d (%c); return %d (%c)\n", c, c, c2, c2); */
49 double_filter (void *opaque, int control,
50 iobuf_t chain, byte *buf, size_t *len)
54 if (control == IOBUFCTRL_DESC)
56 mem2str (buf, "double_filter", *len);
58 if (control == IOBUFCTRL_FLUSH)
62 for (i = 0; i < *len; i ++)
66 rc = iobuf_writebyte (chain, buf[i]);
69 rc = iobuf_writebyte (chain, buf[i]);
78 struct content_filter_state
85 static struct content_filter_state *
86 content_filter_new (const char *buffer)
88 struct content_filter_state *state
89 = malloc (sizeof (struct content_filter_state));
92 state->len = strlen (buffer);
93 state->buffer = buffer;
99 content_filter (void *opaque, int control,
100 iobuf_t chain, byte *buf, size_t *len)
102 struct content_filter_state *state = opaque;
106 if (control == IOBUFCTRL_UNDERFLOW)
108 int remaining = state->len - state->pos;
112 if (toread > remaining)
115 memcpy (buf, &state->buffer[state->pos], toread);
117 state->pos += toread;
130 main (int argc, char *argv[])
135 /* A simple test to make sure filters work. We use a static buffer
136 and then add a filter in front of it that returns every other
139 char *content = "0123456789abcdefghijklm";
145 iobuf = iobuf_temp_with_content (content, strlen (content));
146 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
150 while ((c = iobuf_readbyte (iobuf)) != -1)
152 /* printf ("%d: %c\n", n + 1, (char) c); */
153 assert (content[2 * n + 1] == c);
156 /* printf ("Got EOF after reading %d bytes (content: %d)\n", */
157 /* n, strlen (content)); */
158 assert (n == strlen (content) / 2);
163 /* A simple test to check buffering. Make sure that when we add a
164 filter to a pipeline, any buffered data gets processed by the */
166 char *content = "0123456789abcdefghijklm";
173 iobuf = iobuf_temp_with_content (content, strlen (content));
176 for (i = 0; i < 10; i ++)
178 c = iobuf_readbyte (iobuf);
179 assert (content[i] == c);
183 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
186 while ((c = iobuf_readbyte (iobuf)) != -1)
188 /* printf ("%d: %c\n", n + 1, (char) c); */
189 assert (content[2 * (n - 5) + 1] == c);
192 assert (n == 10 + (strlen (content) - 10) / 2);
198 /* A simple test to check that iobuf_read_line works. */
200 /* - 3 characters plus new line
201 - 4 characters plus new line
202 - 5 characters plus new line
203 - 5 characters, no new line
205 char *content = "abc\ndefg\nhijkl\nmnopq";
212 iobuf = iobuf_temp_with_content (content, strlen(content));
214 /* We read a line with 3 characters plus a newline. If we
215 allocate a buffer that is 5 bytes long, then no reallocation
216 should be required. */
218 buffer = malloc (size);
221 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
223 assert (strcmp (buffer, "abc\n") == 0);
225 assert (max_len == 100);
228 /* We now read a line with 4 characters plus a newline. This
229 requires 6 bytes of storage. We pass a buffer that is 5 bytes
230 large and we allow the buffer to be grown. */
232 buffer = malloc (size);
234 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
236 assert (strcmp (buffer, "defg\n") == 0);
238 /* The string shouldn't have been truncated (max_len == 0). */
239 assert (max_len == 100);
242 /* We now read a line with 5 characters plus a newline. This
243 requires 7 bytes of storage. We pass a buffer that is 5 bytes
244 large and we don't allow the buffer to be grown. */
246 buffer = malloc (size);
248 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
250 /* Note: the string should still have a trailing \n. */
251 assert (strcmp (buffer, "hij\n") == 0);
253 /* The string should have been truncated (max_len == 0). */
254 assert (max_len == 0);
257 /* We now read a line with 6 characters without a newline. This
258 requires 7 bytes of storage. We pass a NULL buffer and we
259 don't allow the buffer to be grown larger than 5 bytes. */
263 n = iobuf_read_line (iobuf, &buffer, &size, &max_len);
265 /* Note: the string should still have a trailing \n. */
266 assert (strcmp (buffer, "mno\n") == 0);
268 /* The string should have been truncated (max_len == 0). */
269 assert (max_len == 0);
276 /* - 10 characters, EOF
279 char *content = "abcdefghijklmnopq";
280 char *content2 = "0123456789";
286 struct content_filter_state *state;
288 iobuf = iobuf_temp_with_content (content, strlen(content));
289 rc = iobuf_push_filter (iobuf,
291 state=content_filter_new (content2));
297 c = iobuf_readbyte (iobuf);
298 if (c == -1 && lastc == -1)
300 /* printf("Two EOFs in a row. Done.\n"); */
309 /* printf("After %d bytes, got EOF.\n", n); */
310 assert (n == 10 || n == 27);
315 /* printf ("%d: '%c' (%d)\n", n, c, c); */
323 /* Write some data to a temporary filter. Push a new filter. The
324 already written data should not be processed by the new
329 char *content = "0123456789";
330 char *content2 = "abc";
334 iobuf = iobuf_temp ();
337 rc = iobuf_write (iobuf, content, strlen (content));
340 rc = iobuf_push_filter (iobuf, double_filter, NULL);
344 rc = iobuf_write (iobuf, content2, strlen (content2) + 1);
347 n = iobuf_temp_to_buffer (iobuf, buffer, sizeof (buffer));
349 printf ("Got %d bytes\n", n);
350 printf ("buffer: `");
351 fwrite (buffer, n, 1, stdout);
352 fputc ('\'', stdout);
353 fputc ('\n', stdout);
356 assert (n == strlen (content) + 2 * (strlen (content2) + 1));
357 assert (strcmp (buffer, "0123456789aabbcc") == 0);
365 char content[] = "0123456789";
370 assert (sizeof buffer == sizeof content - 1);
372 iobuf = iobuf_temp_with_content (content, strlen (content));
375 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
377 rc = iobuf_push_filter (iobuf, every_other_filter, NULL);
380 for (n = 0; (c = iobuf_get (iobuf)) != -1; n ++)
382 /* printf ("%d: `%c'\n", n, c); */
387 assert (buffer[0] == '3');
388 assert (buffer[1] == '7');